#scala #apache-spark-sql #left-join
Вопрос:
У меня есть 2 фрейма данных, и я объединяю эти 2 в зависимости от того, содержится ли строка в одном из столбцов в столбце сообщения в другом фрейме данных.
Пример DFs:
DF1
ID | Приложение | Сообщение |
---|---|---|
1 | не удалось подключиться к facebook. java.lang.Исключение NullPointerException | |
2 | Не удалось установить соединение с приложением .Описание[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. java.lang.Исключение NullPointerException | 10 | java.lang.Исключение NullPointerException | 25 | ДА | |
2 | Не удалось установить соединение с приложением .Описание[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. java.lang.Исключение NullPointerException | 10 | java.lang.Исключение NullPointerException | 25 | yes | |
2 | Не удалось установить соединение с приложением .Описание[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. Спасибо, это помогает!