我有两个空值的数据框,我试图使用PySpark 2.3.0加入:
DFA:
# +----+----+
# |col1|col2|
# +----+----+
# | a|null|
# | b| 0|
# | c| 0|
# +----+----+
DFB:
# +----+----+----+
# |col1|col2|col3|
# +----+----+----+
# | a|null| x|
# | b| 0| x|
# +----+----+----+
使用此脚本可以创建数据框:
dfA = spark.createDataFrame(
[
('a', None),
('b', '0'),
('c', '0')
],
('col1', 'col2')
)
dfB = spark.createDataFrame(
[
('a', None, 'x'),
('b', '0', 'x')
],
('col1', 'col2', 'col3')
)
加入电话:
dfA.join(dfB, dfB.columns[:2], how='left').orderBy('col1').show()
结果:
# +----+----+----+
# |col1|col2|col3|
# +----+----+----+
# | a|null|null| <- col3 should be x
# | b| 0| x|
# | c| 0|null|
# +----+----+----+
预期结果:
# +----+----+----+
# |col1|col2|col3|
# +----+----+----+
# | a|null| x| <-
# | b| 0| x|
# | c| 0|null|
# +----+----+----+
如果我将第一行col2设置为null以外的任何值,那么它是有效的,但我需要支持null值。
我尝试使用条件进行比较,使用此post中概述的null-safe equals,如下所示:
cond = (dfA.col1.eqNullSafe(dfB.col1) & dfA.col2.eqNullSafe(dfB.col2))
dfA.join(dfB, cond, how='left').orderBy(dfA.col1).show()
null-safe join的结果:
# +----+----+----+----+----+
# |col1|col2|col1|col2|col3|
# +----+----+----+----+----+
# | a|null| a|null| x|
# | b| 0| b| 0| x|
# | c| 0|null|null|null|
# +----+----+----+----+----+
这保留了重复的列,我仍然在寻找一种方法来在连接结束时达到预期的结果。
答案 0 :(得分:3)
一个简单的解决方案是select
要保留的列。这将允许您指定它们应来自哪个源数据帧,以及避免重复列问题。
dfA.join(dfB, cond, how='left').select(dfA.col1, dfA.col2, dfB.col3).orderBy('col1').show()
答案 1 :(得分:2)
此操作失败,因为col1
中的orderBy
不明确。您应该引用特定的来源,例如dfA
:
dfA.join(dfB, cond, how='left').orderBy(dfA.col1).show()
答案 2 :(得分:0)
如果你必须在pyspark中用空值连接空值,你应该在连接条件中使用eqnullsafe,然后将空值匹配到空值,spark 2.5版本之后最好使用eqnullsafe,如果需要更多示例{{ 3}}