В чем разница между rowsBetween и rangeBetween?

Из документов PySpark rangeBetween:

rangeBetween(start, end)

Определяет границы фрейма от начала (включительно) до конца (включительно).

Начало и конец относительны от текущей строки. Например, "0" означает "текущая строка", в то время как "-1" означает одно отключение перед текущей строкой, а "5" означает пять отключений после текущей строки.

Parameters:

  • начало - граничное начало, включительно. Кадр не ограничен, если это -sys.maxsize (или ниже).
  • конец - конец границы включительно. Фрейм не ограничен, если это sys.maxsize (или выше). Новое в версии 1.4.

в то время как rowsBetween

rowsBetween(start, end)

Определяет границы фрейма от начала (включительно) до конца (включительно).

И начало, и конец являются относительными позициями из текущей строки. Например, "0" означает "текущая строка", а "-1" означает строку перед текущей строкой, а "5" означает пятую строку после текущей строки.

Parameters:

  • начало - граничное начало, включительно. Кадр не ограничен, если это -sys.maxsize (или ниже).
  • конец - конец границы включительно. Фрейм не ограничен, если это sys.maxsize (или выше). Новое в версии 1.4.

Например, для rangeBetween чем "1 выключен" отличается от "1 строки"?

Ответ 1

Это просто:

  • ROWS BETWEEN не заботится о точных значениях. Он заботится только о порядке строк и принимает фиксированное количество предшествующих и следующих строк при вычислении кадра.
  • RANGE BETWEEN учитывает значения при вычислении кадра.

Давайте использовать пример, используя два определения окна:

  • ORDER BY x ROWS BETWEEN 2 PRECEDING AND CURRENT ROW
  • ORDER BY x RANGE BETWEEN 2 PRECEDING AND CURRENT ROW

и данные как

+---+
|  x|
+---+
| 10|
| 20|
| 30|
| 31|
+---+

Предполагая, что текущая строка является строкой со значением 31 для первого окна, будут включены следующие строки (текущая и две предыдущие):

+---+----------------------------------------------------+
|  x|ORDER BY x ROWS BETWEEN 2  PRECEDING AND CURRENT ROW|
+---+----------------------------------------------------+
| 10|                                               false|
| 20|                                                true|
| 30|                                                true|
| 31|                                                true|
+---+----------------------------------------------------+

и для второго следующего (текущий и все предшествующие, где x> = 31 - 2):

+---+-----------------------------------------------------+
|  x|ORDER BY x RANGE BETWEEN 2  PRECEDING AND CURRENT ROW|
+---+-----------------------------------------------------+
| 10|                                                false|
| 20|                                                false|
| 30|                                                 true|
| 31|                                                 true|
+---+-----------------------------------------------------+

Ответ 2

Документы Java Spark добавляют ясности: https://spark.apache.org/docs/2.3.0/api/java/org/apache/spark/sql/expressions/WindowSpec.html#rowsBetween-long-long-

rangeBetween

Граница на основе диапазона основана на фактическом значении выражения (й) ORDER BY. Смещение используется для изменения значения выражения ORDER BY, например, если текущий порядок по выражению имеет значение 10, а смещение нижней границы равно -3, результирующая нижняя граница для текущей строки будет 10 - 3. = 7. Это, однако, накладывает ряд ограничений на выражения ORDER BY: может быть только одно выражение, и это выражение должно иметь числовой тип данных. Исключение можно сделать, когда смещение не ограничено, поскольку изменение значения не требуется, в этом случае допускается множественное и нечисловое выражение ORDER BY.

rowBetween

Граница на основе строки основана на положении строки в разделе. Смещение указывает количество строк выше или ниже текущей строки, рамка для текущей строки начинается или заканчивается. Например, с учетом скользящей рамки на основе строки со смещением нижней границы -1 и смещением верхней границы +2. Кадр для строки с индексом 5 будет варьироваться от индекса 4 до индекса 6.

Ответ 3

linesBetween: - С помощью rowBetween вы определяете граничный фрейм строк для вычисления, который фрейм рассчитывается независимо.

Фрейм в rowBetween не зависит от предложения orderBy.

df = spark.read.csv(r'C:\Users\akashSaini\Desktop\TT.csv',inferSchema =True, header=True).na.drop()
w =Window.partitionBy('DEPARTMENT').orderBy('SALARY').rowsBetween(Window.unboundedPreceding,Window.currentRow)
df.withColumn('RowsBetween', F.sum(df.SALARY).over(w)).show()


first_name|Department|Salary|RowsBetween|

 Sofia|     Sales| 20000| 20000|
Gordon|     Sales| 25000| 45000|
Gracie|     Sales| 25000| 70000|
Cellie|     Sales| 25000| 95000|
Jervis|     Sales| 30000|125000|
 Akash|  Analysis| 30000| 30000|
Richard|   Account| 12000| 12000|
 Joelly|   Account| 15000| 27000|
Carmiae|   Account| 15000| 42000|
    Bob|   Account| 20000| 62000|
  Gally|   Account| 28000| 90000

rangeBetween: - С помощью rangeBetween вы определяете граничный фрейм строк для вычисления, который может измениться.

Кадр в rowBetween зависит от предложения orderBy. rangeBetween будет включать все строки, которые имеют одинаковое значение в предложении orderBy, как у Gordon, Gracie и Cellie одинаковая зарплата, поэтому они включены в текущий кадр.

Для большего понимания см. пример ниже: -

df = spark.read.csv(r'C:\Users\asaini28.EAD\Desktop\TT.csv',inferSchema =True, header=True).na.drop()
w =Window.partitionBy('DEPARTMENT').orderBy('SALARY').rangeBetween(Window.unboundedPreceding,Window.currentRow)
df.withColumn('RangeBetween', F.sum(df.SALARY).over(w)).select('first_name','Department','Salary','Test').show()

 first_name|Department|Salary|RangeBetween|
  Sofia|     Sales| 20000| 20000|
 Gordon|     Sales| 25000| 95000|
 Gracie|     Sales| 25000| 95000|
 Cellie|     Sales| 25000| 95000|
 Jervis|     Sales| 30000|125000|
  Akash|  Analysis| 30000| 30000|
Richard|   Account| 12000| 12000|
 Joelly|   Account| 15000| 42000|
Carmiae|   Account| 15000| 42000|
    Bob|   Account| 20000| 62000|
  Gally|   Account| 28000| 90000|