我有一个DataFrame,如下所示。
Value1 Value2 Value3
30000 40000 50000
null 20000 10000
另外,我有一个创建为
的UDFval 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替换它。因为,如果我想进行乘法而不是上面的加法,它将会失败。
答案 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 |
+-------+-------+-------+---------+
我希望答案很有帮助