我有两个行数不同的数据框,例如:
val df = sc.parallelize(Array((0, 1.0, 0.4, 0.1),
(1, 0.9, 0.3, 0.3),
(2, 0.2, 0.9, 0.2),
(3, 0.9, 0.2, 0.2)))
.toDF("id", "prop1", "prop2", "prop3")
val df2 = sc.parallelize(Array((0, 3.0, 0.2, 0.1),
(1, 0.9, 0.3, 0.3),
(2, 0.2, 0.5, 0.2),
(3, 0.8, 0.1, 0.1),
(4, 0.3, 0.5, 0.5)))
.toDF("id", "prop1", "prop2", "prop3")
我想使用 id 列作为键来连接两者,所以我这样做:
val joined = df2.join(df, df("id")===df2("id"), "leftouter")
joined.show()
+---+-----+-----+-----+----+-----+-----+-----+
| id|prop1|prop2|prop3| id|prop1|prop2|prop3|
+---+-----+-----+-----+----+-----+-----+-----+
| 0| 3.0| 0.2| 0.1| 0| 1.0| 0.4| 0.1|
| 1| 0.9| 0.3| 0.3| 1| 0.9| 0.3| 0.3|
| 2| 0.2| 0.5| 0.2| 2| 0.2| 0.9| 0.2|
| 3| 0.8| 0.1| 0.1| 3| 0.9| 0.2| 0.2|
| 4| 0.3| 0.5| 0.5|null| null| null| null|
+---+-----+-----+-----+----+-----+-----+-----+
此时有两个问题:
- 为什么要添加第二个 ID 列? 如何摆脱它?
- 如何将空值归零?
要删除第二个"id"列,请先重命名它:
val df = sc.parallelize(Array((0, 1.0, 0.4, 0.1),
(1, 0.9, 0.3, 0.3),
(2, 0.2, 0.9, 0.2),
(3, 0.9, 0.2, 0.2)))
.toDF("id2", "prop1", "prop2", "prop3")
我还重命名了其他列的名称以避免歧义(和AnalysisException
(。
val df2 = sc.parallelize(Array((0, 3.0, 0.2, 0.1),
(1, 0.9, 0.3, 0.3),
(2, 0.2, 0.5, 0.2),
(3, 0.8, 0.1, 0.1),
(4, 0.3, 0.5, 0.5)))
.toDF("id", "prop1_2", "prop2_2", "prop3_2")
现在,drop
不需要的id2
列
val joined = df2.join(df, df("id2")===df2("id"), "outer").drop("id2")
要在空值的情况下提供默认值,请使用 na
和 fill
:
joined.na.fill(0).show
+---+-------+-------+-------+-----+-----+-----+
| id|prop1_2|prop2_2|prop3_2|prop1|prop2|prop3|
+---+-------+-------+-------+-----+-----+-----+
| 0| 3.0| 0.2| 0.1| 1.0| 0.4| 0.1|
| 1| 0.9| 0.3| 0.3| 0.9| 0.3| 0.3|
| 2| 0.2| 0.5| 0.2| 0.2| 0.9| 0.2|
| 3| 0.8| 0.1| 0.1| 0.9| 0.2| 0.2|
| 4| 0.3| 0.5| 0.5| 0.0| 0.0| 0.0|
+---+-------+-------+-------+-----+-----+-----+
有几种方法可以调用fill
,您可以在 API 文档中阅读它。在我提供的示例中,fill(0)
将数字列中的空值替换为值 0
。
只是为了添加到托雷斯答案中,您只能选择您需要显示的内容。像这样的东西: -
joined.select(df2("id"), df("prop1"),df("prop2"),df("prop3")).na.fill(0).show()