在PySpark中,我希望使用键值对进行两个RDD的完全外连接,其中键可以是None
。
例如:
rdd1 = sc.parallelize([(None, "a"), (None, "b")])
rdd2 = sc.parallelize([(None, "c"), (None, "d")])
join_rdd = rdd1.join(rdd2)
看起来PySpark加入了键为None的记录:
print(rdd1.join(rdd2).take(10))
>>> [(None, ('a', 'c')), (None, ('a', 'd')), (None, ('b', 'c')), (None, ('b', 'd'))]
但是,在我加入两个表的SQL中:
Table1: Table2:
key val key val
NULL a NULL c
NULL b NULL d
SELECT * FROM Table1 JOIN Table2 ON Table1.key = Table2.key
我有一个空的结果集。
我认为这是因为在Python中None == None
为真,在SQL NULL = NULL
中为假。
我有两个问题:
有没有办法模仿SQL行为并迫使PySpark不加入Nones?
是错误还是功能?作为SQL用户,我预计通过null键加入不会返回任何内容。我是PySpark的新手,在关于joinig Nones的文档中没有找到任何内容。也许在Spark编程指南中做一些注释是值得的?
或者我错了?
谢谢!
答案 0 :(得分:1)
你的期望是错误的。 RDD API并不遵循SQL语义,而且从不打算这样做。 RDD.join
只是基于哈希的portable_hash
链接,旨在首先提供有意义的None
哈希。
如果你想要类似SQL的语义,你应该使用Spark SQL / Data Frames:
schema = StructType([
StructField("_1", IntegerType(), True), StructField("_2", StringType(), False)
])
df1 = sqlContext.createDataFrame(rdd1, schema)
df2 = sqlContext.createDataFrame(rdd2, schema)
df1.join(df2, ["_1"])
如果您想在RDD上获得类似的结果,请在None
之前过滤掉join
个键:
rdd1.filter(lambda x: x[0] is not None).join(rdd2)