我不确定长时间的工作是否对我这么做但是我在spark 2.2.0中看到了一些意想不到的行为
我创建了一个玩具示例,如下所示
toy_df = spark.createDataFrame([
['p1','a'],
['p1','b'],
['p1','c'],
['p2','a'],
['p2','b'],
['p2','d']],schema=['patient','drug'])
我创建了另一个数据框
mdf = toy_df.filter(toy_df.drug == 'c')
你知道mdf会是
mdf.show()
+-------+----+
|patient|drug|
+-------+----+
| p1| c|
+-------+----+
现在如果我这样做
toy_df.join(mdf,["patient"],"left").select(toy_df.patient.alias("P1"),toy_df.drug.alias('D1'),mdf.patient,mdf.drug).show()
令人惊讶的是我得到了
+---+---+-------+----+
| P1| D1|patient|drug|
+---+---+-------+----+
| p2| a| p2| a|
| p2| b| p2| b|
| p2| d| p2| d|
| p1| a| p1| a|
| p1| b| p1| b|
| p1| c| p1| c|
+---+---+-------+----+
但如果我使用
toy_df.join(mdf,["patient"],"left").show()
我确实看到了预期的行为
patient|drug|drug|
+-------+----+----+
| p2| a|null|
| p2| b|null|
| p2| d|null|
| p1| a| c|
| p1| b| c|
| p1| c| c|
+-------+----+----+
如果我在其中一个数据帧上使用别名表达式,我会得到预期的行为
toy_df.join(mdf.alias('D'),on=["patient"],how="left").select(toy_df.patient.alias("P1"),toy_df.drug.alias("D1"),'D.drug').show()
| P1| D1|drug|
+---+---+----+
| p2| a|null|
| p2| b|null|
| p2| d|null|
| p1| a| c|
| p1| b| c|
| p1| c| c|
+---+---+----+
所以我的问题是在加入后选择列的最佳方法是什么,这种行为是正常的
编辑:根据user8371915,这与标记为
的问题相同
Spark SQL performing carthesian join instead of inner join
但我的问题适用于两个具有相同沿袭并且在调用show方法时执行连接的数据框但是连接后的选择列的行为方式不同。
答案 0 :(得分:3)
最好的方法是使用别名:
toy_df.alias("toy_df") \
.join(mdf.alias("mdf"), ["patient"], "left") \
.select(
col("patient").alias("P1"),
col("toy_df.drug").alias("D1"),
col("patient").alias("patient"),
col("mdf.drug").alias("drug")
) \
.show()
问题是mdf
派生自toy_df
,因此toy_df.drug
和mdf.drug
都引用同一列。因此,当您将它们传递给select
时,Spark也会返回同一列中的值。
答案 1 :(得分:1)
我能够复制你的发现,我希望我能回答为什么会这样。但是,通过更改第二个(右侧)数据集的别名,我能够获得所需的结果。我将mdf.drug更改为mdf.drugs
mdf = toy_df.filter(toy_df.drug == 'c').select(toy_df.patient,toy_df.drug.alias("drugs"))
所以加入后......
toy_df.join(mdf,["patient"],"left").select(toy_df.patient.alias("P1"),toy_df.drug.alias('D1'),mdf.patient,mdf.drugs).show()
我得到了预期的行为
| P1| D1|patient|drugs|
+---+---+-------+-----+
| p2| a| p2| null|
| p2| b| p2| null|
| p2| d| p2| null|
| p1| a| p1| c|
| p1| b| p1| c|
| p1| c| p1| c|
+---+---+-------+-----+
我将进行更多研究,看看我是否可以扩展到这个初步答案