如何优化spark函数以用零替换空值?

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (1)
  • 关注 (0)
  • 查看 (98)

下面是我的Spark函数,它处理DataFrame列中的空值,而不管其数据类型如何。

  def nullsToZero(df:DataFrame,nullsToZeroColsList:Array[String]): DataFrame ={
    var y:DataFrame = df
    for(colDF <- y.columns){
      if(nullsToZeroColsList.contains(colDF)){
        y = y.withColumn(colDF,expr("case when "+colDF+" IS NULL THEN 0 ELSE "+colDF+" end"))
      }
    }
    return y
  }

    import spark.implicits._
    val personDF = Seq(
      ("miguel", Some(12),100,110,120), (null, Some(22),200,210,220), ("blu", None,300,310,320)
    ).toDF("name", "age","number1","number2","number3")
    println("Print Schema")
    personDF.printSchema()
    println("Show Original DF")
    personDF.show(false)
    val myColsList:Array[String] = Array("name","age","age")
    println("NULLS TO ZERO")
    println("Show NullsToZeroDF")
    val fixedDF = nullsToZero(personDF,myColsList)

在上面的代码中,我有一个Integer类型和一个String类型数据类型,两者都是由我的函数处理的。但我怀疑下面的代码,在我的功能中可能会影响性能但不确定。

y = y.withColumn(colDF,expr("case when "+colDF+" IS NULL THEN 0 ELSE "+colDF+" end"))

有没有更优化的方法我可以编写这个函数,有什么意义做.withColumn()并一次又一次地重新分配DF?先感谢您。

提问于
用户回答回答于

我建议根据数据类型组装一个valueMapfor na.fill(valueMap)来填充null具有特定值的列,如下所示:

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

val df = Seq(
  (Some(1), Some("a"), None),
  (None,    Some("b"), Some(20.0)),
  (Some(3), None,      Some(30.0))
).toDF("c1", "c2", "c3")

val valueMap = df.dtypes.collect{ case (c, t) => t match {
  case "StringType" => (c, "n/a")
  case "IntegerType" => (c, 0)
  case "DoubleType" => (c, Double.MinValue)
  // cases for other types as needed ...
} }.toMap
// valueMap: scala.collection.immutable.Map[String,Any] = 
//   Map(c1 -> 0, c2 -> n/a, c3 -> -1.7976931348623157E308)

df.na.fill(valueMap).show
// +---+---+--------------------+
// | c1| c2|                  c3|
// +---+---+--------------------+
// |  1|  a|-1.79769313486231...|
// |  0|  b|                20.0|
// |  3|n/a|                30.0|
// +---+---+--------------------+

扫码关注云+社区

领取腾讯云代金券