1

Condition is: Column names starting with Data-C are StringType columns, Data-D are DateType columns and Data-N are DoubleType columns. I have dataframe in which all column's datatype is a string so I am trying to update their datatype in such way that:

import org.apache.spark.sql.functions._
import sparkSession.sqlContext.implicits._

val diff_set = Seq("col7", "col8", "col15", "Data-C-col1", "Data-C-col3", "Data-N-col2", "Data-N-col4", "Data-D-col16", "Data-D-col18", "Data-D-col20").toSet
var df = (1 to 10).toDF
df = df.select(df.columns.map(c => col(c).as(c)) ++ diff_set.map(c => lit(null).cast("string").as(c)): _*)
df.printSchema()

// This foreach loop yields slow performance
    df.columns.foreach(x => {
      if (x.startsWith("Data-C")) {
        df = df.withColumn(x, col(x).cast(StringType))
      } else if (x.startsWith("Data-D")) {
        df = df.withColumn(x, col(x).cast(DateType))
      } else if (x.startsWith("Data-N")) {
        df = df.withColumn(x, col(x).cast(DoubleType))
      }
    }
    )
df.printSchema()

can this be done more elegantly and efficiently(performance wise) in scala-spark?

1
  • Is below solution working ?? Commented Jun 30, 2020 at 11:18

1 Answer 1

2

Check below code.

scala> df.printSchema
root
 |-- value: integer (nullable = false)
 |-- Data-C-col1: string (nullable = true)
 |-- Data-D-col18: string (nullable = true)
 |-- Data-N-col4: string (nullable = true)
 |-- Data-N-col2: string (nullable = true)
 |-- col15: string (nullable = true)
 |-- Data-D-col16: string (nullable = true)
 |-- Data-D-col20: string (nullable = true)
 |-- col8: string (nullable = true)
 |-- col7: string (nullable = true)
 |-- Data-C-col3: string (nullable = true)

val colum_datatype_mapping = 
Map(
  "Data-C" -> "string",
  "Data-D" -> "date",
  "Data-N" -> "double"
)
val columns = df
.columns
.map { c =>
          val key = c.split("-").init.mkString("-")
          if(colum_datatype_mapping.contains(key)) 
             col(c).cast(colum_datatype_mapping(key)) 
          else 
             col(c)
}
scala> df.select(columns:_*).printSchema
root
 |-- value: integer (nullable = false)
 |-- Data-C-col1: string (nullable = true)
 |-- Data-D-col18: date (nullable = true)
 |-- Data-N-col4: double (nullable = true)
 |-- Data-N-col2: double (nullable = true)
 |-- col15: string (nullable = true)
 |-- Data-D-col16: date (nullable = true)
 |-- Data-D-col20: date (nullable = true)
 |-- col8: string (nullable = true)
 |-- col7: string (nullable = true)
 |-- Data-C-col3: string (nullable = true)

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.