Лучший/эффективный способ отфильтровать строки Spark Dataframe с несколькими условиями

У меня есть фрейм данных, похожий на этот ниже

  id          pub_date   version         unique_id     c_id    p_id    type      source
lni001        20220301      1           64WP-UI-POLI    002     P02    org      internet
lni001        20220301      1           64WP-UI-POLI    002     P02    org      internet
lni001        20220301      1           64WP-UI-POLI    002     P02    org      internet
lni001        20220301      2           64WP-UI-CFGT    012     K21   location  internet
lni001        20220301      2           64WP-UI-CFGT    012     K21   location  internet
lni001        20220301      3           64WP-UI-CFGT    012     K21   location  internet
lni001        20220301      3           64WP-UI-POLI    002     P02    org      internet
lni001        20220301      85          64WP-UI-POLI    002     P02    org      internet
lni001        20220301      85          64WP-UI-POLI    002     P02    org      internet
lni001        20220301      5           64WP-UI-CFGT    012     K21   location  internet
lni002        20220301      1           64WP-UI-CFGT    012     K21   location  internet
 ::
 ::

Я хочу сгруппировать столбец идентификатора и сохранить только самый высокий номер из столбца версии, но здесь есть загвоздка, мне также нужно принять во внимание столбец типа (у которого есть только два типа, организация или местоположение). Окончательный фрейм данных будет выглядеть так, как показано ниже.

  id          pub_date   version         unique_id     c_id    p_id    type      source
lni001        20220301      85          64WP-UI-POLI    002     P02    org      internet
lni001        20220301      85          64WP-UI-POLI    002     P02    org      internet
lni001        20220301      5           64WP-UI-CFGT    012     K21   location  internet
lni002        20220301      14          64WP-UI-CFGT    012     K21   location  internet
 ::
 ::

Мой текущий подход заключается в разделении фрейма данных на два разных: первый — это org в столбце типа, другой — местоположение в столбце типа. Затем я использую groupby, withColumn, но мой фрейм данных огромен. И мне интересно, есть ли более эффективные способы сделать это, возможно, в одной строке кода? Вместо того, чтобы разделять их на два фрейма данных, а затем объединять их вместе?

Спасибо!


36
1

Ответ:

Решено

dense_rank() можно использовать для поиска лучших версий по идентификатору и типу. Это можно использовать для сохранения только верхней записи в каждой группе.

input.withColumn("rank", dense_rank() over (Window.partitionBy($"id",$"type").orderBy($"version".desc)))
  .filter($"rank" === 1)
  .drop($"rank")

Выход:

+------+--------+-------+------------+---+----+--------+--------+
|id    |pub_date|version|unique_id   |_id|p_id|type    |source  |
+------+--------+-------+------------+---+----+--------+--------+
|lni001|20220301|5      |64WP-UI-CFGT|012|K21 |location|internet|
|lni001|20220301|85     |64WP-UI-POLI|002|P02 |org     |internet|
|lni001|20220301|85     |64WP-UI-POLI|002|P02 |org     |internet|
|lni002|20220301|1      |64WP-UI-CFGT|012|K21 |location|internet|
+------+--------+-------+------------+---+----+--------+--------+

Интересные вопросы для изучения