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

Scala 每个Spark UDAF都可以与Window一起使用吗?,scala,apache-spark,dataframe,user-defined-aggregate,Scala,Apache Spark,Dataframe,User Defined Aggregate,我一直认为Spark不允许定义用户定义的窗口函数。我刚刚从这里()测试了“几何平均值”UDAF示例作为一个窗口函数,它似乎工作得很好,例如: 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

我一直认为Spark不允许定义用户定义的窗口函数。我刚刚从这里()测试了“几何平均值”UDAF示例作为一个窗口函数,它似乎工作得很好,例如:

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作为窗口函数。这是否允许,即结果是否正确?顺便说一下,我用的是spark 2.1

编辑:


让我困惑的是,在标准聚合中(即后跟
groupBy
),数据总是添加到缓冲区中,即它们总是会增长,而不会收缩。使用window函数(特别是与
rowsBetween()
)结合使用时,还需要从缓冲区中删除数据,因为“old”元素在沿着排序定义的行移动时将从窗口中删除。我认为窗口函数是沿着状态的顺序移动的。所以我假设一定有类似于“删除”的方法要实现

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

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

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

我最近一直在使用Spark
窗口功能
UDAFs
(Spark 2.0.1),我确认它们配合得非常好。结果是正确的(假设您的UDAF编写正确)。UDAFs的编写有点麻烦,但一旦您得到它,下一个UDAFs的编写速度就会很快


我没有测试所有的函数,但是从
org.apache.spark.sql.functions中构建了聚合函数。在中搜索聚合。我主要使用一些经典的聚合器,如
sum
count
avg
stddev
,它们都返回了正确的值。

让我困惑的是,我总是假设窗口函数也需要实现一个从缓冲区中删除元素的函数(考虑使用(-1,1)
行之间的移动/滚动平均线)但是显然这不是UDAF实现中要考虑的事情,在UDAF中,你必须定义你的缓冲区,如何更新它,如何合并和其他东西……然后
类UserDefinedAggregateFunction
后面的引擎知道如何处理给定范围或行的缓冲区。是的,我知道ch方法实现,但正如我所说,我希望窗口函数有一个定义如何删除元素的方法。随着窗口向前移动,我希望删除最旧的元素并添加新元素。但我现在非常确定情况并非如此,collect\u list似乎为数据帧中的每一行从头开始建立缓冲区,尽管这似乎效率很低。抱歉,可能我们混淆了术语。wind是什么意思ow函数?对于我来说,Spark中有一个应用于窗口的
窗口
+聚合器,这就是我所说的窗口函数。我从来没有遇到过一个官方术语“用户定义的窗口函数”。你问每个Spark UDAF都可以用于窗口吗?答案是肯定的:)我想我们的意思是一样的,对不起,我无法解释我的意思。