【问题标题】:Get the last element of a window in Spark 2.1.1在 Spark 2.1.1 中获取窗口的最后一个元素
【发布时间】:2026-01-22 02:20:15
【问题描述】:

我有一个数据框,其中有子类别,并且想要每个子类别的最后一个元素。

val windowSpec = Window.partitionBy("name").orderBy("count")
sqlContext
    .createDataFrame(
      Seq[(String, Int)](
        ("A", 1),
        ("A", 2),
        ("A", 3),
        ("B", 10),
        ("B", 20),
        ("B", 30)
      ))
    .toDF("name", "count")
    .withColumn("firstCountOfName", first("count").over(windowSpec))
    .withColumn("lastCountOfName", last("count").over(windowSpec))
    .show()

返回给我一些奇怪的东西:

+----+-----+----------------+---------------+                                   
|name|count|firstCountOfName|lastCountOfName|
+----+-----+----------------+---------------+
|   B|   10|              10|             10|
|   B|   20|              10|             20|
|   B|   30|              10|             30|
|   A|    1|               1|              1|
|   A|    2|               1|              2|
|   A|    3|               1|              3|
+----+-----+----------------+---------------+

如我们所见,first 返回的值是正确计算的,但 last 不是,它始终是列的当前值。

有人可以做我想做的事吗?

【问题讨论】:

  • 不是 "orderBy" + "first/last" 在同一列上与 "min"/"max" 相同
  • 可能是;但无论如何我对 max 有相同的行为。
  • 区别在于使用max不需要orderBy,那么当你定义你的windowSpec时只使用partitionBy就可以了。
  • 嗯,删除 orderBy 并使用 max 似乎在我上面的简化案例中有效。但是,在我的实际情况下,我不能这样做,因为我想要最后一个值的数据不是数字。

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


【解决方案1】:

根据问题SPARK-20969,您应该能够通过为窗口定义足够的边界来获得预期的结果,如下所示。

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

val windowSpec = Window
  .partitionBy("name")
  .orderBy("count")
  .rowsBetween(Window.unboundedPreceding, Window.unboundedFollowing)

sqlContext
  .createDataFrame(
    Seq[(String, Int)](
      ("A", 1),
      ("A", 2),
      ("A", 3),
      ("B", 10),
      ("B", 20),
      ("B", 30)
    ))
  .toDF("name", "count")
  .withColumn("firstCountOfName", first("count").over(windowSpec))
  .withColumn("lastCountOfName", last("count").over(windowSpec))
  .show()

或者,如果您在第一个和最后一个计算的同一列上排序,您可以使用非排序窗口更改minmax,那么它也应该可以正常工作。

【讨论】:

    最近更新 更多