【问题标题】:Spark replace all NaNs to null in DataFrame APISpark在DataFrame API中将所有NaN替换为null
【发布时间】:2017-10-06 06:19:52
【问题描述】:

我有一个包含许多双(和/或浮点)列的数据框,其中包含 NaN。我想用 null 替换所有 NaN(即 Float.NaN 和 Double.NaN)。

我可以做到这一点,例如对于单个列x

val newDf = df.withColumn("x", when($"x".isNaN,lit(null)).otherwise($"x"))

这可行,但我想一次对所有列执行此操作。我最近发现了DataFrameNAFunctions (df.na) fill,这听起来正是我需要的。不幸的是,我没有做到以上。 fill 应该用给定值替换所有 NaN 和 null,所以我这样做:

df.na.fill(null.asInstanceOf[java.lang.Double]).show

这给了我一个NullpointerException

还有一个很有前途的replace方法,但是我连代码都编译不了:

df.na.replace("x", Map(java.lang.Double.NaN -> null.asInstanceOf[java.lang.Double])).show

奇怪的是,这给了我

Error:(57, 34) type mismatch;
 found   : scala.collection.immutable.Map[scala.Double,java.lang.Double]
 required: Map[Any,Any]
Note: Double <: Any, but trait Map is invariant in type A.
You may wish to investigate a wildcard type such as `_ <: Any`. (SLS 3.2.10)
    df.na.replace("x", Map(java.lang.Double.NaN -> null.asInstanceOf[java.lang.Double])).show

【问题讨论】:

    标签: scala apache-spark spark-dataframe


    【解决方案1】:

    要在 Spark 中用 null 替换所有 NaN,您只需为每一列创建一个替换值的 Map,如下所示:

    val map = df.columns.map((_, "null")).toMap
    

    然后您可以使用fill 将 NaN(s) 替换为空值:

    df.na.fill(map)
    

    例如:

    scala> val df = List((Float.NaN, Double.NaN), (1f, 0d)).toDF("x", "y")
    df: org.apache.spark.sql.DataFrame = [x: float, y: double]
    
    scala> df.show
    +---+---+
    |  x|  y|
    +---+---+
    |NaN|NaN|
    |1.0|0.0|
    +---+---+
    
    scala> val map = df.columns.map((_, "null")).toMap
    map: scala.collection.immutable.Map[String,String] = Map(x -> null, y -> null)
    
    scala> df.na.fill(map).printSchema
    root
     |-- x: float (nullable = true)
     |-- y: double (nullable = true)
    
    
    scala> df.na.fill(map).show
    +----+----+
    |   x|   y|
    +----+----+
    |null|null|
    | 1.0| 0.0|
    +----+----+
    

    我希望这会有所帮助!

    【讨论】:

    • 谢谢,但我仍然很困惑为什么当您将“null”定义为字符串文字时,这会起作用,这一定是一些内部魔法?
    【解决方案2】:

    要使用 Pyspark API 将所有 NaN 替换为 Spark Dataframe 中的任何值,您可以执行以下操作:

    col_list = [column1,column2] df = df.na.fill(replace_by_value, col_list)

    【讨论】:

      猜你喜欢
      • 2017-05-22
      • 2017-11-01
      • 1970-01-01
      • 1970-01-01
      • 2021-01-02
      • 2022-01-08
      • 2017-07-04
      • 2015-10-20
      • 2018-11-30
      相关资源
      最近更新 更多