PySpark - 来自字典的新列部分正则表达式匹配

PySpark - new column partial regex matching from dictionary

我有一个像这样的 PySpark 数据框:

A B
1 abc_value
2 abc_value
3 some_other_value
4 anything_else

我有一个映射字典:

d = {
"abc":"X",
"some_other":Y,
"anything":Z
}

我需要在我原来的 Dataframe 中创建新的列,应该是这样的:

A B C
1 abc_value X
2 abc_value X
3 some_other_value Y
4 anything_else Z

我试过这样映射:

mapping_expr = f.create_map([f.lit(x) for x in chain(*d.items())]) 然后用 withColumn 应用它,但是它是精确匹配,但是我需要 partial (正则表达式)匹配,如你所见。

请问如何实现?

恐怕在 PySpark 中没有实现根据定义的字典提取子字符串的函数;你可能需要使用技巧。

在这种情况下,您可以先创建一个搜索字符串,其中包含要搜索的所有字典关键字:

keys = list(d.keys())
keys_expr = '|'.join(keys)

keys_expr
# 'abc|some_other|anything'

然后你可以使用 regexp_extractkeys_expr 中提取 第一个 键,我们在 B 列中遇到,如果存在(那是| 运算符的原因)。
最后,您可以使用字典 d 替换新列中的值。

import pyspark.sql.functions as F

df = df\
  .withColumn('C', F.regexp_extract('B', keys_expr, 0))\
  .replace(d, subset=['C'])

df.show()

+---+----------------+---+
|  A|               B|  C|
+---+----------------+---+
|  1|       abc_value|  X|
|  2|       abc_value|  X|
|  3|some_other_value|  Y|
|  4|   anything_else|  Z|
+---+----------------+---+