在 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+ 中,要找到(移动)中位数,我们可以使用函数 percentilepercentile_approx。以下答案在 PySpark 中使用 expr 来计算移动中位数作为窗口函数 - 您应该能够按照自己的方式进入 Scala:***.com/questions/44061553/… 【参考方案1】:

不幸的是,我相信您不能在窗口函数中使用UDFsUDAFs。窗口函数不是 Spark 的原生函数——它们使用 Hive,这排除了使用 Spark 定义的 UDFsUDAFs

理论上,我想您可以直接在 Hive 中创建 UDAF,然后从 Spark 中调用它。但这不是我以前尝试过的东西——似乎它必须是可能的。

【讨论】:

以上是关于在 Apache Spark SQL 中将中值作为窗口函数 (UDAF) 移动的主要内容,如果未能解决你的问题,请参考以下文章

如何在火花中将rdd对象转换为数据框

在 spark sql 中将字符串类型转换为数组类型

Scala - 如何在 Spark SQL 查询中将日期字符串转换为时间戳?

spark中将每个组作为新数据帧并在循环中传递另一个函数的最佳方法是啥?

在 org.apache.spark.sql.types.DataTypes 中找不到 uuid

如何在 Scala 中将 Spark DataFrames 一一添加到 Seq()