Scala / Apache Spark转换DataFrame列值和类型,否则为多个

时间:2017-09-11 23:46:15

标签: sql scala apache-spark cassandra

我有一个主要的SQL表,我正在读取Spark并修改为写入CassandraDB。目前我有一个工作实现,用于将性别从0,1,2,3(整数)转换为"男性","女性"," Trans"等(字符串)。虽然下面的方法确实有效,但使用这些映射到DataFrame中创建一个单独的Array,将它连接到主表/ DataFrame,然后删除,重命名等等,效率似乎非常低效。

我见过:

.withColumn("gender", when(col("gender) === 1, "male").otherwise("female") 

这将允许我继续在主表上进行方法链接,但是无法使用2个以上的选项。有没有办法做到这一点?我在这个表上有大约10个不同的列,每个列都需要创建自己的自定义转换。由于此代码将处理数据的TB,因此实现此目的的重复性和效率更低。感谢您提前提供任何帮助!

case class Gender(tmpid: Int, tmpgender: String)

private def createGenderDf(spark:SparkSession): DataFrame = {
  import spark.implicits._
  Seq(
    Gender(1, "Male"),
    Gender(2, "Female"),
    Gender(777, "Prefer not to answer")
  ).toDF
}


private def createPersonsDf(spark: SparkSession): DataFrame = {
  val genderDf = createGenderDf(spark)
  genderDf.show()

  val personsDf: DataFrame = spark.read
    .format("csv")
    .option("header", "true")
    .option("inferSchema", "true")
    .option("delimiter", "\t")
    .load(dataPath + "people.csv")
    .withColumnRenamed("ID", "id")
    .withColumnRenamed("name_first", "firstname")

  val personsDf1: DataFrame = personsDf
    .join(genderDf, personsDf("gender") === genderDf("tmpid"), "leftouter")

  val personsDf2: DataFrame = personsDf1
    .drop("gender")
    .drop("tmpid")
    .withColumnRenamed("tmpgender", "gender")
}

1 个答案:

答案 0 :(得分:1)

您可以使用嵌套的when功能,这样就无需创建genderDfjoindroprename等等。至于您的示例可以做以下

import org.apache.spark.sql.functions._
import org.apache.spark.sql.types.StringType
personsDf.withColumn("gender", when(col("gender") === 1, "male").otherwise(when(col("gender") ===2, "female").otherwise("Prefer not to answer")).cast(StringType))

您可以在上面的嵌套结构中添加更多when函数,也可以为其他10列重复相同的操作。