Spark:从 Window 获取行值

Spark: get rows value from a Window

我用 spark 定义了一个 Window:

val window = Window
  .partitionBy("myaggcol")
  .orderBy("datefield")
  .rowsBetween(-2, 0)

然后我可以从 window' 行计算一个新列,例如:

dataset
  .withColumn("newcol", last("diffcol").over(window) - first("diffcol").over(window))

这将为每个点计算 "diffcol" 与第 n-2 行的差异。

现在我的问题是:如何获取第 n-1 行的 "diffcol",不是第一行也不是最后一行,而是中间行?

如果我对你的问题的理解正确,Window 函数 lag 会比 rowsBetween 更好,如下例所示:

import org.apache.spark.sql.functions._
import org.apache.spark.sql.expressions.Window
import spark.implicits._

val df = Seq(
  ("a", 1, 100), ("a", 2, 200), ("a", 3, 300), ("a", 4, 400),
  ("b", 1, 500), ("b", 2, 600), ("b", 3, 700)
).toDF("c1", "c2", "c3")

val win = Window.partitionBy("c1").orderBy("c2")

df.
  withColumn("c3Diff1", $"c3" - coalesce(lag("c3", 1).over(win), lit(0))).
  withColumn("c3Diff2", $"c3" - coalesce(lag("c3", 2).over(win), lit(0))).
  show
// +---+---+---+-------+-------+
// | c1| c2| c3|c3Diff1|c3Diff2|
// +---+---+---+-------+-------+
// |  b|  1|500|    500|    500|
// |  b|  2|600|    100|    600|
// |  b|  3|700|    100|    200|
// |  a|  1|100|    100|    100|
// |  a|  2|200|    100|    200|
// |  a|  3|300|    100|    200|
// |  a|  4|400|    100|    200|
// +---+---+---+-------+-------+