每个 Spark UDAF 都可以与 Window 一起使用吗?

Can every Spark UDAF be used with Window?

我一直认为 Spark 不允许定义 User-Defined-Window-Functions。我刚刚从这里 (https://docs.databricks.com/spark/latest/spark-sql/udaf-scala.html) 测试了 "Geometric Mean" UDAF 示例作为 window 函数,它似乎工作得很好,例如:

val geomMean = new GeometricMean

(1 to 10).map(i=>
  (i,i.toDouble)
)
.toDF("i","x")
.withColumn("geom_mean",geomMean($"x").over(Window.orderBy($"i").rowsBetween(-1,1)))
.show()

+---+----+------------------+
|  i|   x|         geom_mean|
+---+----+------------------+
|  1| 1.0|1.4142135623730951|
|  2| 2.0|1.8171205928321397|
|  3| 3.0|2.8844991406148166|
|  4| 4.0|3.9148676411688634|
|  5| 5.0|  4.93242414866094|
|  6| 6.0| 5.943921952763129|
|  7| 7.0| 6.952053289772898|
|  8| 8.0| 7.958114415792783|
|  9| 9.0| 8.962809493114328|
| 10|10.0| 9.486832980505138|
+---+----+------------------+

我从未见过 spark 文档谈论将 UDAF 用作 window 函数。这是允许的,即结果是否正确?顺便说下我用的是spark 2.1

编辑:

让我感到困惑的是,在标准聚合中(即后跟 groupBy),数据总是添加到缓冲区中,即它们将始终增长,永远不会缩小。使用 window 函数(特别是与 rowsBetween() 结合使用),数据也需要从缓冲区中移除,因为 "old" 元素在移动时会从 window 中删除排序定义的行。我想到了 window-functions 来移动一个状态的排序。所以我假设必须要实施类似 "remove" 的方法

我不确定你的问题到底是什么。

Can every Spark UDAF be used with Window?

以下是我在这个话题上的个人经验:

我最近一直在使用 Spark window functionsUDAFs (Spark 2.0.1),我确认它们可以很好地协同工作。结果是正确的(假设你的 UDAF 是正确的)。 UDAF 写起来有点痛苦,但是一旦你掌握了它,下一个就会很快。

我没有测试所有这些,但是 org.apache.spark.sql.functions._ 的内置聚合函数也对我有用。在 functions 中搜索 聚合。我主要使用一些经典聚合器,如 sumcountavgstddev,它们都返回了正确的值。