加入PySpark加入无值

时间:2016-03-02 17:06:31

标签: python join apache-spark null pyspark

在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中为假。

我有两个问题:

  1. 有没有办法模仿SQL行为并迫使PySpark不加入Nones?

  2. 是错误还是功能?作为SQL用户,我预计通过null键加入不会返回任何内容。我是PySpark的新手,在关于joinig Nones的文档中没有找到任何内容。也许在Spark编程指南中做一些注释是值得的?

  3. 或者我错了?

    谢谢!

1 个答案:

答案 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)