Spark 提供了以下示例作为WindowSpec
类的rangeBetween
方法的方法文档:
import org.apache.spark.sql.expressions.Window
import spark.implicits._
val df = Seq((1, "a"), (1, "a"), (2, "a"), (1, "b"), (2, "b"), (3, "b")).toDF("id", "category")
val byCategoryOrderedById = Window.partitionBy('category).orderBy('id).rangeBetween(Window.currentRow, 1)
df.withColumn("sum", sum('id) over byCategoryOrderedById).show()
结果是:
+---+--------+---+
| id|category|sum|
+---+--------+---+
| 1| b| 3|
| 2| b| 5|
| 3| b| 3|
| 1| a| 4|
| 1| a| 4|
| 2| a| 2|
+---+--------+---+
对于具有值b
的category
,我能够理解sum
列中的值:
row#1(1-b-3), 3=1+2 //2 is next id for this row
row#2(2-b-5), 5=2+3 //3 is next id for this row
row#3(3-b-3), 3=3 //there is no next row since this is the last row for b
但是对于值a
category
,我无法理解4 4 2是如何计算的
rangeBetween
考虑列中的实际值。它将检查哪些值"在范围内"(包括开始值和结束值)。在您的示例中,当前行是起始值,下一行是结束值。由于范围是包含的,因此所有重复值也将计算在内。
例如,如果开始值和结束值分别为 1 和 3。此范围 (1,2,3) 中的所有值都将用于总和。
这与rowsBetween
形成鲜明对比。对于此函数,仅计算指定的行。也就是说,rowsBetween(Window.currentRow, 1)
只会考虑当前和下一行,无论是否存在重复项。
我猜对于同一类别中的相同id,这些相同的id(这里id为1,类别为a)是一起计算的...,即:
对于同一类别中的两个相同 ID:
-
将所有相同的ID相加,这里,它是1 + 1
-
对于这些相同的 id,它们的下一个 id 是与他们不同的 id,这里是 2,然后总和是 1+1+2
不确定我的理解是否正确