How to access the last two character of each cell of Spark DataFrame to do some calculations on its value using Scala

Viewed 99

I am using Spark with Scala. After loading the data to Spark Dataframe, I want to access each cell of the Dataframe to do some calculations. The code is in the following:

val spark = SparkSession
.builder
.master("local[4]")
.config("spark.executor.memory", "8g")
.config("spark.executor.cores", 4)
.config("spark.task.cpus",1)
.appName("Spark SQL basic example")
.config("spark.some.config.option", "some-value")
.getOrCreate()

val df = spark.read
.format("jdbc") 
.option("url", "jdbc:oracle:thin:@x.x.x.x:1521:orcldb")
.option("dbtable", "table")
.option("user", "orcl")
.option("password", "*******")
.load()

val row_cnt = df.count()
for(i<-0 to row_cnt.toInt){
  val t = df.select("CST_NUM").take(i)
  println("start_date:",t)
}

The Output is like this:

(start_date:,[Lorg.apache.spark.sql.Row;@38ae69f7)

I can access value of each cell using forEach; but,I cannot return it to another function. Would you please guide me how to access value of each cell of Spark Dataframe?

any help is really appreciated.

1 Answers

You need to learn how to work with Spark efficiently - right now your code isn't very optimal. I recommend to read first chapters of the Learning Spark, 2ed book to understand how to work with Spark - it's freely downloadable from Databricks' site.

Regarding your case, you need to change your code just to do the single .select instead of doing it in the loop. And then you can return your data to caller. But it will depend on the amount of data that you need to return - usually you should return Dataframe itself (maybe only subset of columns), and people will transform data as they need. In this case you can take advantage of distributed computation.

If you have a small dataset (hundreds/thousands of rows), then you can materialize dataset as a Spark/Java collection & return it to caller. For example, this could be done as following:

val t = df.select("CST_NUM")
val coll = t.collect().map(_.getInt(0))

in this case, we're selecting only one column from our dataframe (CST_NUM), then use .collect to bring all rows to the driver node, and then extracting the column value from the row object (I've used .getInt for that, but you can use something else from the Row API, find a function that matches the type of your column - .getLong, .getString, etc.)

Related