处理Dataframe中的空值

时间:2017-08-04 06:22:39

标签: scala apache-spark dataframe

我有一个DataFrame,如下所示。

Value1 Value2 Value3
30000  40000  50000
null   20000  10000

另外,我有一个创建为

的UDF
val testUDF=udf((a: Double, b: Double, c: Double) => {
   if(a==null && b!=null && c!=null)
       b+c
   else
       a+b+c
})

我的代码如下。

input.withColumn("checkNull", testUDF(col("value1"),col("value2"),col("value3"))).show

结果数据框为

Value1 Value2 Value3 checkNull
30000  40000  50000  120000
null   20000  10000   null

这里,显示为null,而不是为“checkNUll”列显示第二行的3000。我在代码中做错了什么? 我不想用0替换它。因为,如果我想进行乘法而不是上面的加法,它将会失败。

3 个答案:

答案 0 :(得分:2)

有很多方法可以做你想做的事情和当前的信息,我建议使用coalesce

df.withColumn("x4", 
                   coalesce(
                        $"x1".cast("long") * $"x2" * $"x3", 
                        $"x2".cast("long") * $"x3", 
                        lit(0)
                   )
  ).show
+-----+-----+-----+--------------+
|   x1|   x2|   x3|            x4|
+-----+-----+-----+--------------+
|30000|40000|50000|60000000000000|
| null|20000|10000|     200000000|
+-----+-----+-----+--------------+

由于此问题Why do these two multiplication operations give different results?

,我正在投靠long

这是填充列x1的另一个解决方案,其中1乘以:

df.na.fill(1, Seq("x1")).withColumn("x4", $"x1".cast("long") * $"x2" * $"x3").show

它产生相同的结果。

另一个选择是执行以下操作:

df.withColumn("x4", 
                when($"x1".isNull and $"x2".isNotNull and $"x3".isNotNull, $"x2".cast("long") * $"x3")
                .otherwise($"x1".cast("long") * $"x2"* $"x3")
  ).show

我建议您阅读以下关于Dealing with Null in Apache Spark的条目。

答案 1 :(得分:0)

你必须在这种情况下使用过滤器,因为当value1为null时,它不会调用udf。

val testStr = """[{"Val1":1000, "Val2":2000, "Val3":4000},{"Val2":2000, "Val3":4000}]"""
    val rdd = sc.parallelize(Seq(testStr))
          val df = sqlContext.read.json(rdd)

          val newdf = df.filter(df.col("Val1").isNotNull).withColumn("checkNull",df.col("Val1")+df.col("Val2")+df.col("Val3"))
            val newdfw2 = df.filter(df.col("Val1").isNull).withColumn("checkNull",df.col("Val2")+df.col("Val3"))
            val alldf = newdf.unionAll(newdfw2)
          alldf.show()

答案 2 :(得分:0)

您只需使用na.fill(0.0)将所有null值替换为0.0,然后使用+表示法将列值添加为

df.select($"Value1".cast(DoubleType), $"Value2".cast(DoubleType), $"Value3".cast(DoubleType))
    .na.fill(0.0)
    .withColumn("checkNull", $"Value1"+$"Value2"+$"Value3")
    .show(false)

将数据框设为

+------+------+------+
|Value1|Value2|Value3|
+------+------+------+
|30000 |40000 |50000 |
|null  |20000 |10000 |
+------+------+------+

你应该输出

+-------+-------+-------+---------+
|Value1 |Value2 |Value3 |checkNull|
+-------+-------+-------+---------+
|30000.0|40000.0|50000.0|120000.0 |
|0.0    |20000.0|10000.0|30000.0  |
+-------+-------+-------+---------+

我希望答案很有帮助