我一直以为Spark不允许定义User-Defined-Window-Functions。我刚刚测试了"几何平均值" UDAF示例来自此处(https://docs.databricks.com/spark/latest/spark-sql/udaf-scala.html)作为窗口函数,它似乎工作得很好,例如:
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|
+---+----+------------------+
我从未见过火花文档谈论使用UDAF作为窗口函数。这是允许的,即结果是否正确?我顺便使用spark 2.1
编辑:
令我困惑的是,在标准聚合中(即后跟groupBy
),数据总是被添加到缓冲区,即它们将始终增长,永不缩小。使用窗口函数(特别是与rowsBetween()
一起使用),还需要从缓冲区中删除数据,因为" old"当元素沿着排序定义的行移动时,元素将从窗口中掉出。我认为窗口函数沿着状态的顺序移动。所以我认为必须有像"删除"要实施的方法
答案 0 :(得分:3)
我不确定你的问题到底是什么。
每个Spark UDAF都可以与Window一起使用吗?
是
以下是我在此主题中的个人经历:
我最近一直在使用Spark window functions
和UDAFs
(Spark 2.0.1)工作,我确认它们能很好地协同工作。结果是正确的(假设你的UDAF写得正确)。 UDAF写起来有点痛苦,但是一旦你得到它,下一个就会很快。
我没有测试所有这些,但org.apache.spark.sql.functions._
的内置聚合函数也适用于我。在functions中搜索聚合。我主要使用一些经典聚合器,例如sum
,count
,avg
,stddev
,它们都返回了正确的值。