PySpark — новое соответствие частичного регулярного выражения столбца из словаря

#python #regex #apache-spark #pyspark #mapping

Вопрос:

У меня есть фрейм данных PySpark, похожий на этот:

A B
1 значение abc_value
2 значение abc_value
3 какое-то другое значение
4 anything_else

У меня есть картографический словарь:

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

Мне нужно создать новый столбец в моем исходном фрейме данных, который должен быть таким:

A B C
1 значение abc_value X
2 значение abc_value X
3 какое-то другое значение Y
4 anything_else Z

Я попробовал составить карту так:

mapping_expr = f.create_map([f.lit(x) for x in chain(*d.items())]) а затем примените его, withColumn однако это точное соответствие, однако мне нужно частичное (регулярное выражение), как вы можете видеть.

Как это сделать, пожалуйста?

Ответ №1:

Я боюсь, что в PySpark нет реализованной функции, которая извлекает подстроки в соответствии с определенным словарем; вам, вероятно, придется прибегнуть к трюкам.

В этом случае вы можете сначала создать строку поиска, которая включает в себя все ключи вашего словаря для поиска:

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

keys_expr
# 'abc|some_other|anything'
 

Затем вы можете использовать regexp_extract для извлечения первый ключ из keys_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|
 --- ---------------- ---