Apache spark Pyspark连接,然后列选择显示意外输出
我不确定长时间的工作是否对我有影响,但我在spark 2.2.0中看到了一些意想不到的行为 我创建了一个玩具示例,如下所示Apache spark Pyspark连接,然后列选择显示意外输出,apache-spark,pyspark,Apache Spark,Pyspark,我不确定长时间的工作是否对我有影响,但我在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') 如你
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.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|
+---+---+----+
如果我在其中一个数据帧上使用别名表达式,我会得到预期的行为
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|
+---+---+----+
所以我的问题是,在联接之后选择列的最佳方式是什么?这种行为正常吗
编辑:根据用户8371915,这与标记为但我的问题适用于两个具有相同血统的dataframe,它们在调用show方法时执行联接,但联接后的select列的行为不同 我能够复制你的发现,我希望我能回答为什么会发生这种情况。但是,我只需更改第二个(右侧)数据集的别名,就可以得到您想要的结果。我把mdf药物改成了mdf药物
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|
+---+---+-------+-----+
我将做更多的研究,看看是否可以扩展到这个初始答案最好的方法是使用别名:
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也会从同一列返回值。由于df.col
或df['col']
的结果是一个列
类型,它不绑定到数据帧,因此我相信结果是预期的。我想知道为什么在错误的情况下选择时没有出现不明确的列名
错误。通常,共享同一沿袭的数据帧
之间的连接可能会导致轻微的真/假谓词。这个案子应该是自动处理的,但看起来事情好像是从裂缝中溜走了。诚实的建议-始终使用别名。可能重复的@user8371915看起来不像同一个问题。