удаление/обновление строк фрейма данных spark на основе значений в других столбцах

#scala #apache-spark-sql #left-join

Вопрос:

У меня есть 2 фрейма данных, и я объединяю эти 2 в зависимости от того, содержится ли строка в одном из столбцов в столбце сообщения в другом фрейме данных.

Пример DFs:

DF1

ID Приложение Сообщение
1 Facebook не удалось подключиться к facebook. java.lang.Исключение NullPointerException
2 Google Не удалось установить соединение с приложением .Описание[stepupRequestId:может не иметь значения null ]
3 домашний горшок PorcupineCourier-Не удалось установить выполнение подключения к приложению. java.lang.Исключение NullPointerException

DF2

Идентификатор события Знак Сортировщик Экшен
10 java.lang.Исключение NullPointerException 25 ДА
20 Дикобраз-Курьер-Исполнение 9 НЕТ
30 stepupRequestId:может быть не равен нулю 1 НЕТ

Если я сделаю левое соединение этих 2 кадров данных, как показано ниже

val result1 = df1.join(df2, $»Сообщение.содержит($»Токен»), слева)

вывод DF выглядит следующим образом

ID Приложение Сообщение Идентификатор события Знак Сортировщик Экшен
1 Facebook не удалось подключиться к facebook. java.lang.Исключение NullPointerException 10 java.lang.Исключение NullPointerException 25 ДА
2 Google Не удалось установить соединение с приложением .Описание[stepupRequestId:может не иметь значения null ] 30 stepupRequestId:может быть не равен нулю 1 НЕТ
3 домашний горшок PorcupineCourier-Не удалось установить выполнение подключения к приложению. java.lang.Исключение NullPointerException 20 Дикобраз-Курьер-Исполнение 9 НЕТ
3 домашний горшок PorcupineCourier-Не удалось установить выполнение подключения к приложению. java.lang.Исключение NullPointerException 10 java.lang.Исключение NullPointerException 25 ДА

Сообщение = «PorcupineCourier-Не удалось установить выполнение подключения к приложению. java.lang.Исключение NullPointerException» в DF1 содержит несколько токенов, и в итоге у меня получается 2 совпадения для одного и того же сообщения в выводе.

Но я хотел бы использовать столбец SortOrder в DF2, чтобы получить правильное соответствие и удалить дублирующуюся строку.Я хотел бы получить Event_Id с самым низким сортировщиком в случае совпадения нескольких токенов, поэтому в приведенном выше выводе Event_Id = 20 имеет самый низкий сортировщик, мой вывод должен содержать только 3 строки, как показано ниже

Ожидаемые результаты :

ID Приложение Сообщение Идентификатор события Знак Сортировщик Экшен
1 Facebook не удалось подключиться к facebook. java.lang.Исключение NullPointerException 10 java.lang.Исключение NullPointerException 25 yes
2 Google Не удалось установить соединение с приложением .Описание[stepupRequestId:может не иметь значения null ] 30 stepupRequestId:может быть не равен нулю 1 no
3 домашний горшок PorcupineCourier-Не удалось установить выполнение подключения к приложению. java.lang.Исключение NullPointerException 20 Дикобраз-Курьер-Исполнение 9 no

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

Я застрял и был бы признателен за любую помощь в правильном понимании логики

Ответ №1:

Чтобы удалить дубликат. Это довольно стандартный шаблон для удаления повторяющихся строк.

 result1.withColumn("rn", row_number over Window.partitionBy('Id).orderBy('SortOrder, 'Event_Id)).where('rn === 1)
 

Мы ставим сортировщик в качестве первого критерия ранжирования, затем Event_id. Это по своей природе в порядке возрастания. Если у вас есть нули, вы можете сделать .asc_nulls_last это в столбце сортировки

Я реализовал более внутреннюю версию этого здесь: https://github.com/kanielc/jarvis-utils/blob/d95442ffad1d61d9269e87228e0911508784655f/src/main/scala/com/jarvis/utils/DatasetFunctions.scala#L27

но вышеприведенная версия будет работать так же хорошо.

Комментарии:

1. Спасибо, это помогает!