在 PySpark 中使用 regexp_extract 提取多个单词

Exo*_*mus 1 python apache-spark apache-spark-sql pyspark

我有一个包含一些单词的列表,我需要从文本行中提取匹配的单词,我找到了这个,但它只提取了一个单词。

密钥文件内容

这是一个关键字

部分描述文件内容

32015 这是一个关键字 hello world

代码

import pyspark.sql.functions as F

keywords = sc.textFile('file:///home/description_search/keys') #1
part_description =  sc.textFile('file:///description_search/part_description') #2
keywords = keywords.map(lambda x: x.split(' ')) #3
keywords = keywords.collect()[0] #4
df = part_description.map(lambda r: Row(r)).toDF(['line']) #5
df.withColumn('extracted_word', F.regexp_extract(df['line'],'|'.join(keywords), 0)).show() #6
Run Code Online (Sandbox Code Playgroud)

输出

+--------------------+--------------+
|                line|extracted_word|
+--------------------+--------------+
|32015   this is a...|          this|
+--------------------+--------------+
Run Code Online (Sandbox Code Playgroud)

预期产出

+--------------------+-----------------+
|                line|   extracted_word|
+--------------------+-----------------+
|32015   this is a...|this,is,a,keyword|
+--------------------+-----------------+
Run Code Online (Sandbox Code Playgroud)

我想要

  1. 返回所有匹配的关键字及其计数

  2. ifstep #4是最有效的方法

可重现的例子:

+--------------------+--------------+
|                line|extracted_word|
+--------------------+--------------+
|32015   this is a...|          this|
+--------------------+--------------+
Run Code Online (Sandbox Code Playgroud)

Zyg*_*ygD 5

Spark 3.1+regexp_extract_all可用:

regexp_extract_all(str, regexp[, idx])- 提取与表达式str匹配regexp并对应于正则表达式组索引的所有字符串。

您原来的问题现在可以这样解决:

re_pattern = '(' + '|'.join([fr'\\b{k}\\b' for k in keywords]) + ')'
df = df.withColumn('matched', F.expr(f"regexp_extract_all(line, '{re_pattern}', 1)"))
df = df.withColumn('count', F.size('matched'))

df.show()
#+--------------------+--------------------+-----+
#|                line|             matched|count|
#+--------------------+--------------------+-----+
#|32015 this is a k...|[this, is, a, key...|    4|
#|        keyword this|     [keyword, this]|    2|
#|32015 this is a k...|[this, is, a, key...|    8|
#|     keyword keyword|  [keyword, keyword]|    2|
#|                is a|             [is, a]|    2|
#+--------------------+--------------------+-----+
Run Code Online (Sandbox Code Playgroud)