了解Spark WindowSpec#rangeBetween

时间:2017-11-05 08:13:41

标签: scala apache-spark apache-spark-sql

Spark提供以下示例作为rangeBetween类的WindowSpec方法的方法文档:

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|
+---+--------+---+

对于值category的{​​{1}},我能够理解b列中的值:

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 的{​​{1}},我无法理解如何计算4 4 2

2 个答案:

答案 0 :(得分:2)

rangeBetween会考虑列中的实际值。它将检查哪些值在“范围内”(包括开始值和结束值)。在您的示例中,当前行是起始值,下一行是结束值。由于范围是包含的,因此所有重复值也将计算

例如,如果开始值和结束值分别为1和3。此范围内的所有值(1,2,3)将用于总和。

这与rowsBetween形成鲜明对比。对于此函数,仅计算指定的行。即,rowsBetween(Window.currentRow, 1)将仅考虑当前行和下一行,无论是否存在重复行。

答案 1 :(得分:0)

我猜想对于相同类别中的相同ID,这些相同的ID(此处,id为1,类别为a)一起计算......,即:

对于同一类别中的两个相同ID:

  1. 总结所有相同的ID,这里是1 + 1

  2. 对于这些相同的id,他们的下一个id是与他们不同的id,这里是2,那么总和是1 + 1 + 2

  3. 不确定我的理解是否正确