Функции Spark Window: рассчитывается один раз за кадр / диапазон? - PullRequest
1 голос
/ 03 апреля 2020

Это вопрос об оконных функциях в Spark.

Предположим, у меня есть этот DF

DATE_S | ID | STR | VALUE
-------------------------
1      | 1  | A   | 0.5
1      | 1  | A   | 1.23
1      | 1  | A   | -0.4
2      | 1  | A   | 2.0
3      | 1  | A   | -1.2
3      | 1  | A   | 0.523
1      | 2  | A   | 1.0
2      | 2  | A   | 2.5
3      | 2  | A   | 1.32
3      | 2  | A   | -3.34
1      | 1  | B   | 1.5
1      | 1  | B   | 0.23
1      | 1  | B   | -0.3
2      | 1  | B   | -2.0
3      | 1  | B   | 1.32
3      | 1  | B   | 523.0
1      | 2  | B   | 1.3
2      | 2  | B   | -0.5
3      | 2  | B   | 4.3243
3      | 2  | B   | 3.332

Это всего лишь пример! Предположим, что есть намного больше DATE_S для каждого (ID, STR) , много других идентификаторов и STR и еще много записей для (DATE_S, ID, STR). Очевидно, есть несколько значений для каждой комбинации (DATE_S, ID, STR)

Теперь я делаю это:

val w = Window.partitionBy("ID", "STR").orderBy("DATE_S").rangeBetween(-N, -1)
df.withColumn("RESULT", function("VALUE").over(w))

, где N может привести к включению большого диапазон строк, от 100 до 100000 и более, в зависимости от («ID», «STR»)

Результат будет примерно таким

DATE_S | ID | STR | VALUE | RESULT
----------------------------------
1      | 1  | A   | 0.5   | R1
1      | 1  | A   | 1.23  | R1
1      | 1  | A   | -0.4  | R1
2      | 1  | A   | 2.0   | R2
3      | 1  | A   | -1.2  | R3
3      | 1  | A   | 0.523 | R3
1      | 2  | A   | 1.0   | R4
2      | 2  | A   | 2.5   | R5
3      | 2  | A   | 1.32  | R6
3      | 2  | A   | -3.34 | R7
1      | 1  | B   | 1.5   | R8
1      | 1  | B   | 0.23  | R8
1      | 1  | B   | -0.3  | R9
2      | 1  | B   | -2.0  | R10
3      | 1  | B   | 1.32  | R11
3      | 1  | B   | 523.0 | R11
1      | 2  | B   | 1.3   | R12
2      | 2  | B   | -0.5  | R13
3      | 2  | B   | 4.3243| R14
3      | 2  | B   | 3.332 | R14

Есть идентичные «РЕЗУЛЬТАТ» s потому что для каждой строки с одинаковыми (DATE_S, ID, ST) значения, которые go в расчете «функции», одинаковы.

Мой вопрос такой:

Спарк вызывает "функцию" для каждой строки (пересчитывает одно и то же значение несколько раз) или вычисляет ее один раз для диапазона (кадра?) значений и просто вставляет их на всех строках, попадающих в диапазон?

Спасибо за чтение:)

1 Ответ

2 голосов
/ 03 апреля 2020

Судя по вашим данным, результат может отличаться, если запустить его дважды, как я вижу, поскольку нет четкой возможности упорядочения. Но мы оставим это в стороне.

Несмотря на то, что есть оптимизация кода, нигде нельзя найти, чтобы он проверял, как вы заявляете, является ли следующий вызов тем же набором данных для обработки для следующей строки. Я никогда не читал об этом типе оптимизации. Это происходит из-за ленивого подхода к оценке, но это другое дело. Таким образом, для каждой строки он вычисляется снова.

Из большого источника: https://jaceklaskowski.gitbooks.io/mastering-spark-sql/spark-sql-functions-windows.html

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

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

Самой большой проблемой является подходящее количество разделов для параллельной обработки, что дорого, но это большие данные. partitionBy("ID", "STR") здесь ключ, и это хорошо.

...