Как удалить дубликаты строк в spark dataframe на основе пользовательской логики?

#scala #apache-spark #apache-spark-sql

#scala #apache-spark #apache-spark-sql

Вопрос:

У меня есть spark dataframe, который выглядит следующим образом:

 Id,timestamp,index,target
id1,2020-04-03,1,34
id1,2020-04-03,2,37
id1,2020-04-04,1,31
id1,2020-04-05,1,29
id2,2020-04-03,1,35
...
  

Фрейм данных разбивается в кластере на столбцы «Id».

Я хочу убедиться, что нет строк с повторяющимися значениями «Id» и «timestamp».
Если есть повторяющиеся записи, я хочу выбрать строку с меньшим значением «index».
(Если есть повторяющиеся строки с одинаковыми записями в «Id», «timestamp», «index»; тогда выбор любой из строк подходит)

Итак, приведенный выше dataframe после удаления дублирования должен выглядеть следующим образом:

 Id,timestamp,index,target
id1,2020-04-03,1,34
id1,2020-04-04,1,31
id1,2020-04-05,1,29
id2,2020-04-03,1,35
...
  

Обратите внимание, что вторая строка <id1,2020-04-03,2,37> была удалена.

Поскольку фрейм данных уже разделен на «Id», я надеюсь найти способ, при котором не требуется связь между разделами, что делает операцию очень эффективной.

Ответ №1:

 val df = Seq(
  ("id1", "2020-04-03", "2", "34"),
  ("id1", "2020-04-03", "3", "34"),
  ("id1", "2020-04-03", "1", "37"),
  ("id1", "2020-04-03", "5", "34"),
  ("id1", "2020-04-04", "1", "31"),
  ("id1", "2020-04-05", "1", "29"),
  ("id2", "2020-04-03", "1", "35")).toDF("Id", "timestamp", "index", "target")

df.sort("index").dropDuplicates("Id", "timestamp").orderBy("timestamp").show()
 --- ---------- ----- ------ 
| Id| timestamp|index|target|
 --- ---------- ----- ------ 
|id1|2020-04-03|    1|    37|
|id2|2020-04-03|    1|    35|
|id1|2020-04-04|    1|    31|
|id1|2020-04-05|    1|    29|
 --- ---------- ----- ------ 
  

Вы можете сортировать по индексу, а затем использовать удаление дубликатов для достижения и сохранения более низкого индекса.

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

1. Я предполагаю, что это работает, но, как следует из вопроса, не использует тот факт, что DF уже разделен по идентификатору заранее, и что это можно использовать, чтобы избежать перетасовки, которую вы sort делаете. На мой взгляд (но я недостаточно обдумал это), изменение вашего вида на id, timestamp, index в таком порядке было бы более эффективным. Поскольку DF разделяется по идентификатору, это не должно удлиняться, и тогда выпадающие дубликаты естественным образом сохранят самый низкий индекс.