首页 > 解决方案 > PySpark:检查数组中的值是否在列中

问题描述

我想检查数组中是否有任何值:

list = ['dog', 'mouse', 'horse', 'bird']

出现在 PySpark 数据框列中:

文本 是列表
我喜欢我的两只狗 真的
不知道要不要养猫 错误的
安娜像鸟儿一样唱歌 真的
马场是个好地方 真的

我发现如果人们倾向于使用多个单词,dog|mouse|horse|bird但我有很多单词,我想使用一个数组。请问你能帮帮我吗?

标签: apache-sparkpysparkapache-spark-sql

解决方案


如果要使用数组,则需要对transform数组进行rlike比较:

import pyspark.sql.functions as F

word_list = ['dog', 'mouse', 'horse', 'bird']

df2 = df.withColumn(
    'words',
    F.array(*[F.lit(w) for w in word_list])
).withColumn(
    'isList',
    F.expr("array_max(transform(words, x -> lower(text) rlike x))")
).drop('words')

df2.show(20,0)
+------------------------------------+------+
|text                                |isList|
+------------------------------------+------+
|I like my two dogs                  |true  |
|I don't know if I want to have a cat|false |
|Anna sings like a bird              |true  |
|Horseland is a good place           |true  |
+------------------------------------+------+

filter也可以对数组进行操作,您可以在其中测试过滤后的数组的大小(使用匹配的单词):

df2 = df.withColumn(
    'words',
    F.array(*[F.lit(w) for w in word_list])
).withColumn(
    'isList',
    F.expr("size(filter(words, x -> lower(text) rlike x)) > 0")
).drop('words')

如果您喜欢使用aggregate它也是可能的:

df2 = df.withColumn(
    'words',
    F.array(*[F.lit(w) for w in word_list])
).withColumn(
    'isList',
    F.expr("aggregate(words, false, (acc, x) -> acc or lower(text) rlike x)")
).drop('words')

请注意,所有这三个高阶函数都需要 Spark >= 2.4。


推荐阅读