У меня проблема с извлечением регулярных выражений с несколькими совпадениями - PullRequest
0 голосов
/ 08 февраля 2019

Я пытаюсь извлечь 60 мл и 0,5 мл из строки "60 мл парацетомола и 0,5 мл XYZ".Эта строка является частью столбца X в фрейме данных spark.Хотя я могу протестировать свой код регулярного выражения для извлечения 60 ML и 0,5 ML в валидаторе регулярных выражений, я не могу извлечь его с помощью regexp_extract, поскольку он нацелен только на 1-е совпадение.Следовательно, я получаю только 60 мл.

Можете ли вы предложить мне лучший способ сделать это с использованием UDF?

1 Ответ

0 голосов
/ 08 февраля 2019

Вот как это можно сделать с помощью пользовательского интерфейса Python:

from pyspark.sql.types import *
from pyspark.sql.functions import *
import re

data = [('60 ML of paracetomol and 0.5 ML of XYZ',)]
df = sc.parallelize(data).toDF('str:string')

# Define the function you want to return
def extract(s)
    all_matches = re.findall(r'\d+(?:.\d+)? ML', s)
    return all_matches

# Create the UDF, note that you need to declare the return schema matching the returned type
extract_udf = udf(extract, ArrayType(StringType()))

# Apply it
df2 = df.withColumn('extracted', extract_udf('str'))

Пользовательские функции Python значительно снижают производительность по сравнению с собственными операциями DataFrame.Подумав немного подробнее, вот еще один способ сделать это без использования UDF.Основная идея - заменить весь текст, который вам не нужен, запятыми, а затем разделить запятыми, чтобы создать массив окончательных значений.Если вам нужны только цифры, вы можете обновить регулярные выражения, чтобы убрать ML из группы захвата.

pattern = r'\d+(?:\.\d+)? ML'
split_pattern = r'.*?({pattern})'.format(pattern=pattern)
end_pattern = r'(.*{pattern}).*?$'.format(pattern=pattern)

df2 = df.withColumn('a', regexp_replace('str', split_pattern, '$1,'))
df3 = df2.withColumn('a', regexp_replace('a', end_pattern, '$1'))
df4 = df3.withColumn('a', split('a', r','))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...