从数组列中删除多个项目而不循环

问题描述 投票:0回答:1

PySpark 提供

array_remove(column: Column, element: Any)
函数,该函数在删除所有等于该元素的值后返回该列。
AIP 文档示例:

>>> df = spark.createDataFrame([([1, 2, 3, 1, 1],), ([],)], ['data'])
>>> df.select(array_remove(df.data, 1)).collect()
[Row(array_remove(data, 1)=[2, 3]), Row(array_remove(data, 1)=[])]

我想知道是否有任何简单的方法(除了做一个简单的

for
循环)使用此函数从列中删除多个元素(在列表中提供)。

注意:正如jxc指出的,可以使用

array_except()
方法。但是,对于我的用例,我需要在过滤后将数组的项目保持相同的顺序,并且当我使用
array_except
进行测试时,未保持顺序。

python arrays loops apache-spark pyspark
1个回答
0
投票

这里有一些选项。它们的不同之处在于如何处理重复项空值

from pyspark.sql import functions as F
df = spark.createDataFrame([([1, 2, 3, 2, 1, None, None],), ([3, 2, 1, 2, 3, None, None],)], ['data'])

df = df.withColumns({
    'option_1': F.array_except('data', F.lit([2, 4])),
    'option_2': F.filter('data', lambda x: ~x.isin([2, 4])),
    'option_3': F.filter('data', lambda x: ~x.isin([2, 4]) | x.isNull()),
    'option_4': F.filter('data', lambda x: ~F.array_contains(F.lit([2, 4]), x)),
    'option_5': F.filter('data', lambda x: ~F.array_contains(F.lit([2, 4]), x) | x.isNull()),
})
df.show(truncate=0)
# +---------------------------+------------+---------+---------------------+---------+---------------------+
# |data                       |option_1    |option_2 |option_3             |option_4 |option_5             |
# +---------------------------+------------+---------+---------------------+---------+---------------------+
# |[1, 2, 3, 2, 1, NULL, NULL]|[1, 3, NULL]|[1, 3, 1]|[1, 3, 1, NULL, NULL]|[1, 3, 1]|[1, 3, 1, NULL, NULL]|
# |[3, 2, 1, 2, 3, NULL, NULL]|[3, 1, NULL]|[3, 1, 3]|[3, 1, 3, NULL, NULL]|[3, 1, 3]|[3, 1, 3, NULL, NULL]|
# +---------------------------+------------+---------+---------------------+---------+---------------------+
© www.soinside.com 2019 - 2024. All rights reserved.