如何连接具有不同行数的数据框
how to join data frames with different number of rows
我有两个行数不同的数据框,例如:
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 documentation 中阅读相关内容。在我提供的示例中,fill(0)
将数字列中的空值替换为值 0
.
只要添加到 Torres Answer 中,您就可以 select 只显示您需要显示的内容。像这样:-
joined.select(df2("id"), df("prop1"),df("prop2"),df("prop3")).na.fill(0).show()
我有两个行数不同的数据框,例如:
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 documentation 中阅读相关内容。在我提供的示例中,fill(0)
将数字列中的空值替换为值 0
.
只要添加到 Torres Answer 中,您就可以 select 只显示您需要显示的内容。像这样:-
joined.select(df2("id"), df("prop1"),df("prop2"),df("prop3")).na.fill(0).show()