我在执行以下代码时遇到了问题:
from pyspark.sql import functions as F
from pyspark.sql import Row, HiveContext
hc = HiveContext()
rows1 = [Row(id1 = '2', id2 = '1', id3 = 'a'),
Row(id1 = '3', id2 = '2', id3 = 'a'),
Row(id1 = '4', id2 = '3', id3 = 'b')]
df1 = hc.createDataFrame(rows1)
df2 = df1.filter(F.col("id3")=="a")
df3 = df1.join(df2, df1.id2 == df2.id1, "inner")
当我运行上面的代码时,df3是一个空的DataFrame。然而: 如果我将代码更改为下面,它将给出正确的结果(2行的DataFrame):
from pyspark.sql import functions as F
from pyspark.sql import Row, HiveContext
hc = HiveContext()
rows1 = [Row(id1 = '2', id2 = '1', id3 = 'a'),
Row(id1 = '3', id2 = '2', id3 = 'a'),
Row(id1 = '4', id2 = '3', id3 = 'b')]
df1 = hc.createDataFrame(rows1)
rows2 = [Row(id1 = '2', id2 = '1', id3 = 'a'),
Row(id1 = '3', id2 = '2', id3 = 'a'),
Row(id1 = '4', id2 = '3', id3 = 'b')]
df1_temp = hc.createDataFrame(rows2)
df2 = df1_temp.filter(F.col("id3")=="a")
df3 = df1.join(df2, df1.id2 == df2.id1, "inner")
所以我的问题是:为什么我必须在这里创建一个临时数据帧? 另外,如果我无法在项目中获得HiveContext,如何在现有数据框之上创建重复的数据框?
答案 0 :(得分:5)
我相信你在这里遇到的问题是一个更普遍的问题的实例,其中某些类型的DataFrame自连接(包括DataFrame与其自身的过滤副本的连接)可能导致产生模糊或不正确查询计划。
有几个Spark JIRA与此相关;这里有一些值得注意的:
还有其他JIRA门票处理这些问题的不同表现/方面。这些门票可以通过从上面列出的门票开始的JIRA“涉及”链接链接发现。
这种歧义只会在通过DataFrame实例引用列时产生(通过下标,如df["mycol"]
,或通过字段访问,如df.mycol
)。通过别名DataFrame并通过别名引用列可以避免这种不明确性。例如,以下工作正常:
>>> from pyspark.sql import functions as F
>>> df1 = hc.createDataFrame(rows1).alias("df1")
>>> df2 = df1.filter(F.col("id3")=="a").alias("df2")
>>> df3 = df1.join(df2, F.col("df1.id2") == F.col("df2.id1"), "inner")
>>> df3.show()
+---+---+---+---+---+---+
|id1|id2|id3|id1|id2|id3|
+---+---+---+---+---+---+
| 4| 3| b| 3| 2| a|
| 3| 2| a| 2| 1| a|
+---+---+---+---+---+---+
答案 1 :(得分:1)
我在Spark 2.0中看到与此数据集相同的行为,但并不总是针对相同的操作。稍微不同的数据框架工作正常。
df1 = spark.createDataFrame(
[(1, 2, 'a'), (2, 2, 'a'), (3, 4, 'b')], ['id1', 'id2', 'id3']
)
df1.show()
+---+---+---+
|id1|id2|id3|
+---+---+---+
| 1| 2| a|
| 2| 2| a|
| 3| 4| b|
+---+---+---+
df2 = df1.filter(df1.id3 == 'a')
df2.show()
+---+---+---+
|id1|id2|id3|
+---+---+---+
| 1| 2| a|
| 2| 2| a|
+---+---+---+
df3 = df1.join(df2, df1.id2 == df2.id1, 'inner')
df3.show()
+---+---+---+---+---+---+
|id1|id2|id3|id1|id2|id3|
+---+---+---+---+---+---+
| 2| 2| a| 1| 2| a|
| 2| 2| a| 2| 2| a|
+---+---+---+---+---+---+
一定有错误吗?我没有尝试过后期版本的火花。您可能希望将此报告为错误。