在 Apache Spark SQL 中将中值作为窗口函数 (UDAF) 移动
Posted
技术标签:
【中文标题】在 Apache Spark SQL 中将中值作为窗口函数 (UDAF) 移动【英文标题】:moving median as a window function (UDAF) in Apache Spark SQL 【发布时间】:2016-06-06 15:27:48 【问题描述】:我正在尝试将“移动中位数”函数实现为窗口函数,以便在 Apache Spark SQL 中使用它。
我正在尝试在 Scala 中将其实现为 UDAF。 Spark 的版本是 1.6.1。
我尝试了两种调用我的 UDAF(“中位数”)的方法:
1) 作为 SQL 查询:
val timeSeries = ... // get a DataFrame
...
timeSeries.registerTempTable("time_series")
timeSeries.sqlContext.udf.register("median", new MedianUDAF)
val timeSeriesWithMovingAverage = timeSeries.sqlContext.sql(s"select *, median(value_column) over (partition by metrics_name order by time_column) from time_series")
结果是:
Failure(org.apache.spark.sql.AnalysisException: 找不到窗口函数中位数;)
2) 作为 DataFrame API 调用:
val timeSeriesWithMovingAverage = timeSeries.withColumn("movingAvg", medianFunction(timeSeries("value_column")).over(windowSpec))
结果是:
Failure(java.lang.UnsupportedOperationException: MedianUDAF(value#16) 在窗口操作中不受支持。)
有没有办法将 UDAF 用作窗口函数? 例如,计算移动中位数(不是移动平均线而是中位数)。
【问题讨论】:
在 Spark 2.1+ 中,要找到(移动)中位数,我们可以使用函数percentile
和 percentile_approx
。以下答案在 PySpark 中使用 expr
来计算移动中位数作为窗口函数 - 您应该能够按照自己的方式进入 Scala:***.com/questions/44061553/…
【参考方案1】:
不幸的是,我相信您不能在窗口函数中使用UDFs
或UDAFs
。窗口函数不是 Spark
的原生函数——它们使用 Hive,这排除了使用 Spark 定义的 UDFs
和 UDAFs
。
理论上,我想您可以直接在 Hive 中创建 UDAF
,然后从 Spark 中调用它。但这不是我以前尝试过的东西——似乎它必须是可能的。
【讨论】:
以上是关于在 Apache Spark SQL 中将中值作为窗口函数 (UDAF) 移动的主要内容,如果未能解决你的问题,请参考以下文章
Scala - 如何在 Spark SQL 查询中将日期字符串转换为时间戳?
spark中将每个组作为新数据帧并在循环中传递另一个函数的最佳方法是啥?