#regex #apache-spark #pyspark #databricks #azure-databricks
#регулярное выражение #apache-spark #pyspark #databricks #azure-databricks
Вопрос:
У меня есть pyspark dataframe (df), который содержит столбец даты (тип данных: str) и столбец сообщений (тип данных str изменен из объекта списка с помощью concat_ws ()), как показано ниже:
Пример dataframe
Date message
2020-11-01 ['some not required text1', 'Startstring ID :AB_CD',
'some not required text2', 'ID :EDGH', 'some not
required text3', 'ID :XYZ', 'Stopstring' 'some not
required text4', 'Startstring ID :cd_ab', 'some not
required text5', 'ID :ghed',
'some not required text6', ID :zyx', 'Stopstring 'some
not required text7']
2020-11-02 ['some not required text8', Startstring 'ID :ABCD',
'some not required text9', 'ID :ED_GH', 'some not
required text10', ID :X_YZ, Stopstring 'some not
required text11', 'Startstring
ID :cdab', 'some not required text12', 'ID :gh_ed',
'some not required text13', ID :z_yx', 'Stopstring
'some not required text14']
Я хочу извлечь первое вхождение строки сразу после ID: между Startstring и Stopstring и отбросить идентификаторы, которые не являются первым появлением. За одну дату может быть несколько таких экземпляров.
Ожидаемый результат:
Date message
2020-11-01 AB_CD
2020-11-01 cd_ab
2020-11-02 ABCD
2020-11-02 cdab
Я попытался извлечь первое вхождение строки сразу после ID: as:
import pyspark.sql.functions as F
from pyspark.sql.types import *
result = df.withColumn("message", F.regexp_extract(col("message"), r"Startstring[sS]*?ID :s*(S*)b[sS]*? Stopstring",1))
result.show()
Это дает мне только строку сразу после ID: в первый раз за определенную дату, как показано ниже:
Date message
2020-11-01 AB_CD
2020-11-02 ABCD
Помощь в этом отношении высоко ценится. Спасибо
Ответ №1:
Что вы могли бы сделать, это:
- объедините массив (как вы описали)
- разделение на «Стоп-строку»
- разнесите столбец, что означает, что вы получаете строку для каждого элемента массива (и, следовательно, для каждого вхождения вашего шаблона).
- примените регулярное выражение.
df
.withColumn("concat_message", F.concat_ws(" ",F.col("message")))
.withColumn("split_message", F.split(F.col("concat_message"), "Stopstring"))
.withColumn("exploded_message", F.explode(F.col("split_message")))
.withColumn("parsed_ids", F.regexp_extract(F.col("exploded_message"), r"Startstring[sS]*?ID :s*(S*)b[sS]*?",1))
.filter(F.col("parsed_ids") != "")
.show()
Одна из проблем заключается в том, что при разделении с помощью «Stopmessage» это слово удаляется из результирующих строк и не может использоваться в шаблоне регулярных выражений.
Комментарии:
1. Спасибо за ваш ответ. Я получаю сообщение об ошибке при запуске этого скрипта в databricks. «org.apache.spark.SparkException: задание прервано из-за сбоя этапа: задача 1 на этапе 100.0 выполнялась 4 раза, последний сбой: потерянная задача 1.3 на этапе 100.0 (TID 1425, 10.139.64.5, исполнитель 17): ExecutorLostFailure (executor 17 завершается из-за одной из запущенных задач) Причина: удаленный RPC-клиент отключен. Вероятно, из-за превышения пороговых значений контейнеров или проблем с сетью. Проверьте журналы драйверов на наличие предупреждающих сообщений «.
2. Я решил это. ваш код дает неправильный ответ. Спасибо
3. Ваше сообщение об ошибке звучит как проблема с сетью, а не проблема с кодом… Если вы считаете, что предоставленный ответ неверен, и нашли лучшее решение, было бы неплохо поделиться им здесь для последующего использования.
4. Да, понял, что ошибка произошла из-за проблемы с сетью. Я решил это. Однако ваш код не генерирует соответствующий вывод. В любом случае, я сделал код самостоятельно.