上下文:
我需要使用 isin 函数根据包含另一个数据帧列的内容过滤数据帧。

对于使用 Pandas 的 Python 用户,这将是:isin()。
对于 R 用户,这将是:%in%。

所以我有一个带有 id 列的简单 Spark 数据框:

l = [(1, 12), (1, 44), (1, 3), (2, 54), (3, 18), (3, 11), (4, 13), (5, 78)]
df = spark.createDataFrame(l, ['id', 'value'])
df.show()

+---+-----+
| id|value|
+---+-----+
|  1|   12|
|  1|   44|
|  1|    3|
|  2|   54|
|  3|   18|
|  3|   11|
|  4|   13|
|  5|   78|
+---+-----+

我想获得多次出现的所有 id。这是 df 中唯一 ID 的数据框:
unique_ids = df.groupBy('id').count().where(col('count') < 2)
unique_ids.show()

+---+-----+
| id|count|
+---+-----+
|  5|    1|
|  2|    1|
|  4|    1|
+---+-----+

所以逻辑操作是:
 df = df[~df.id.isin(unique_ids.id)]
 # This is the same than:
 df = df[df.id.isin(unique_ids.id) == False]

但是,我得到一个空的数据框:
df.show()

+---+-----+
| id|value|
+---+-----+
+---+-----+

这个“错误”以相反的方式工作:
df[df.id.isin(unique_ids.id)]

返回 df 的所有行。

最佳答案

表达式 df.id.isin(unique_ids.id) == False 正在评估是否为 Column<b'((id IN (id)) = false)'> 并且这永远不会发生,因为 id 在 id 中。然而,表达式 df.id.isin(unique_ids.id) 正在评估 if Column<b'(id IN (id))'> ,这总是正确的,因此它返回整个数据帧。 unique_ids.id 是一个列而不是一个列表。
isin(*cols) 接收 值列表 作为参数,而不是列,因此,要以这种方式工作,您应该执行以下操作:

ids = unique_ids.rdd.map(lambda x:x.id).collect()
df[df.id.isin(ids)].collect() # or show...

你将获得:
[Row(id=2, value=54), Row(id=4, value=13), Row(id=5, value=78)]

无论如何,我认为如果您加入两个数据框会更好:
df_ = df.join(unique_ids, on='id')

得到:
df_.show()
+---+-----+-----+
| id|value|count|
+---+-----+-----+
|  5|   78|    1|
|  2|   54|    1|
|  4|   13|    1|
+---+-----+-----+

关于python - PySpark:使用 isin 过滤返回空数据帧,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/55046432/

10-10 21:39
查看更多