火花:数据帧.subtract当key不是R中的第一个时返回所有值

2024-10-05 14:24:03 发布

您现在位置:Python中文网/ 问答频道 /正文

我试图在spark1.6.1中使用SQLContext.subtract()从一个数据帧中移除基于另一个数据帧中的列的行。我们举个例子:

from pyspark.sql import Row

df1 = sqlContext.createDataFrame([
    Row(name='Alice', age=2),
    Row(name='Bob', age=1),
]).alias('df1')

df2 = sqlContext.createDataFrame([
    Row(name='Bob'),
])

df1_with_df2 = df1.join(df2, 'name').select('df1.*')
df1_without_df2 = df1.subtract(df1_with_df2)

因为我需要df1中不包括name='Bob'的所有行,所以我希望Row(age=2, name='Alice')。但我也找回了鲍勃:

^{pr2}$

在进行了各种各样的实验之后,我发现问题出在age键上。如果我省略它:

df1_noage = sqlContext.createDataFrame([
    Row(name='Alice'),
    Row(name='Bob'),
]).alias('df1_noage')

df1_noage_with_df2 = df1_noage.join(df2, 'name').select('df1_noage.*')
df1_noage_without_df2 = df1_noage.subtract(df1_noage_with_df2)
print(df1_noage_without_df2.collect())
# [Row(name='Alice')]

那我就如期得到爱丽丝了。我所做的最奇怪的观察是,可以添加键,只要它们位于我在join中使用的键之后的(在字典顺序意义上):

df1_zage = sqlContext.createDataFrame([
    Row(zage=2, name='Alice'),
    Row(zage=1, name='Bob'),
]).alias('df1_zage')

df1_zage_with_df2 = df1_zage.join(df2, 'name').select('df1_zage.*')
df1_zage_without_df2 = df1_zage.subtract(df1_zage_with_df2)
print(df1_zage_without_df2.collect())
# [Row(name='Alice', zage=2)]

我正确地理解了爱丽丝(和她的扎格)!在我的实际示例中,我对所有列都感兴趣,而不仅仅是name之后的列。在


Tags: nameagewithrowwithoutbobdf1df2
1条回答
网友
1楼 · 发布于 2024-10-05 14:24:03

这里有一些bug(第一个问题看起来与SPARK-6231有关),JIRA看起来是个好主意,但是SUBTRACT/EXCEPT不是部分匹配的正确选择。相反,您可以使用反连接:

df1.join(df1_with_df2, ["name"], "leftanti").show()

在1.6中,您可以使用标准外部联接执行几乎相同的操作:

^{pr2}$

相关问题 更多 >