pyspark数据框中的正则表达式

时间:2020-09-30 12:01:24

标签: pyspark

我有一个类似的数据框

df = spark.createDataFrame(
    [
        (1, 'foo,foobar,something'),
        (2, 'bar,fooaaa'),
    ],
    ['id', 'txt']
)
df.show()
+---+--------------------+
| id|                 txt|
+---+--------------------+
|  1|foo,foobar,something|
|  2|    bar,awdaw,fooaaa|
+---+--------------------+

现在,我只想在“ txt”列中保留包含某些单词的行,就得到了像regex = '(foo|other)'这样的正则表达式。

如果我这样做,df = df.filter(df.txt.rlike(regex))也会因为“ fooaaa”而保留第2行。 如何正确执行此操作?

注意:正则表达式是输入,并且是任意的。我不能在这里简单地添加\b

我尝试了df.select("id", f.split("txt", ",").alias("txt")),但是我有一个列表,不能再使用rlike

+---+----------------------+
| id|                   txt|
+---+----------------------+
|  1|[foo,foobar,something]|
|  2|    [bar,awdaw,fooaaa]|
+---+----------------------+

是否有一个函数可以在pyspark数据框中的每一行的字符串列表中搜索一个字符串?

2 个答案:

答案 0 :(得分:1)

我有一些适合您当前示例的内容,但有很多限制。我们可以做得更好。

df.withColumn("extract", F.regexp_extract("txt", regex, 0)).where(
    "array_contains(split(txt, ','), extract)"
).show()

+---+--------------------+-------+
| id|                 txt|extract|
+---+--------------------+-------+
|  1|foo,foobar,something|    foo|
+---+--------------------+-------+

答案 1 :(得分:0)

对于Spark 2.4+,您可以在拆分后使用内置existsrlikeSQL functions的组合。这样,可以使用rlike分别测试数组的每个元素。

df.withColumn("flag", F.expr("exists(split(txt, ','), x -> x rlike '^(foo|other)$')")) \
   .show()

输出:

+---+--------------------+-----+
| id|                 txt| flag|
+---+--------------------+-----+
|  1|foo,foobar,something| true|
|  2|          bar,fooaaa|false|
+---+--------------------+-----+