Есть 3 способа сделать это (один вы уже знаете из другого ответа).Я избегаю collect
, так как он на самом деле не нужен.
Вот набор данных с максимальным значением 3, появляющимся дважды.
val tags = Seq(
("tg1", 1), ("tg2", 2), ("tg1", 3), ("tg4", 4), ("tg3", 3)
).toDF("tag", "value")
scala> tags.show
+---+-----+
|tag|value|
+---+-----+
|tg1| 1|
|tg2| 2|
|tg1| 3| <-- maximum value
|tg4| 4|
|tg3| 3| <-- another maximum value
+---+-----+
Декартово соединение с набором данных "Max"
Я собираюсь использовать декартово объединение tags
и однорядный набор данных с максимальным значением.
val maxDF = tags.select(max("value") as "max")
scala> maxDF.show
+---+
|max|
+---+
| 4|
+---+
val solution = tags.crossJoin(maxDF)
scala> solution.show
+---+-----+---+
|tag|value|max|
+---+-----+---+
|tg1| 1| 4|
|tg2| 2| 4|
|tg1| 3| 4|
|tg4| 4| 4|
|tg3| 3| 4|
+---+-----+---+
Я не беспокоюсь о декартовом объединении здесь, так как это всего лишь одно-row набор данных.
Оконная агрегация
Моя любимая оконная агрегация прекрасно подходит для этой задачи.С другой стороны, я не думаю, что это был бы самый эффективный подход из-за количества используемых разделов, то есть только 1, что дает наихудший параллелизм.
Хитрость заключается в использованиифункция агрегирования max
над спецификацией пустого окна, которая сообщает Spark SQL об использовании всех строк в любом порядке.
val solution = tags.withColumn("max", max("value") over ())
scala> solution.show
18/05/31 21:59:40 WARN WindowExec: No Partition Defined for Window operation! Moving all data to a single partition, this can cause serious performance degradation.
+---+-----+---+
|tag|value|max|
+---+-----+---+
|tg1| 1| 4|
|tg2| 2| 4|
|tg1| 3| 4|
|tg4| 4| 4|
|tg3| 3| 4|
+---+-----+---+
Обратите внимание на предупреждение, в котором все сказано.
WindowExec: раздел не определен для работы с окном!Перемещение всех данных в один раздел может привести к серьезному снижению производительности.
Я бы не стал использовать этот подход с учетом других решений и оставляю его здесь для образовательных целей.