Apache spark 如何计算数据帧中的移动中值?
是否有方法计算spark DataFrame中属性的移动中值 我希望可以使用窗口函数(通过使用(0,10)之间的Apache spark 如何计算数据帧中的移动中值?,apache-spark,apache-spark-sql,Apache Spark,Apache Spark Sql,是否有方法计算spark DataFrame中属性的移动中值 我希望可以使用窗口函数(通过使用(0,10)之间的行定义窗口)来计算移动中值,但没有计算它的功能(类似于平均值或平均值)。我认为您在这里几乎没有选择 前向窗函数 我认为ntile(2)(在一个行窗口上)会给你两个“段”,你可以用它们来计算窗口上的中值 引述: ntile(n:Int)窗口函数:返回有序窗口分区中的ntile组id(从1到n,包括1到n)。例如,如果n为4,则第一季度的行将获得值1,第二季度将获得值2,第三季度将获得值3
行定义窗口)来计算移动中值,但没有计算它的功能(类似于平均值或平均值)。我认为您在这里几乎没有选择
前向窗函数
我认为ntile(2)
(在一个行窗口上)会给你两个“段”,你可以用它们来计算窗口上的中值
引述:
ntile(n:Int)窗口函数:返回有序窗口分区中的ntile组id(从1到n,包括1到n)。例如,如果n为4,则第一季度的行将获得值1,第二季度将获得值2,第三季度将获得值3,最后一季度将获得值4
这相当于SQL中的NTILE函数
如果一个组中的行数大于另一个组中的行数,请从较大的组中选择最大的行数
如果组中的行数为偶数,则取每组中的最大行数和最小行数,然后计算中位数
我发现它在中描述得很好
百分比秩窗口函数
我认为,percent\u rank
也可能是计算行窗口中位数的一个选项
引述:
percent\u rank()窗口函数:返回窗口分区内行的相对排名(即百分位)
计算方法如下:
(其分区中的行的排名-1)/(分区中的行数-1)
这相当于SQL中的PERCENT_RANK函数
用户定义聚合函数(UDAF)
您可以编写一个用户定义的聚合函数(UDAF)来计算窗口上的中值
UDAF扩展为(引用scaladoc):
用于实现用户定义的聚合函数(UDAF)的基类
幸运的是,示例中有一个自定义UDAF的示例实现。下面是一个类I扩展的UserDefinedAggregateFunction,用于获取移动中值
class MyMedian extends org.apache.spark.sql.expressions.UserDefinedAggregateFunction {
def inputSchema: org.apache.spark.sql.types.StructType =
org.apache.spark.sql.types.StructType(org.apache.spark.sql.types.StructField("value", org.apache.spark.sql.types.DoubleType) :: Nil)
def bufferSchema: org.apache.spark.sql.types.StructType = org.apache.spark.sql.types.StructType(
org.apache.spark.sql.types.StructField("window_list", org.apache.spark.sql.types.ArrayType(org.apache.spark.sql.types.DoubleType, false)) :: Nil
)
def dataType: org.apache.spark.sql.types.DataType = org.apache.spark.sql.types.DoubleType
def deterministic: Boolean = true
def initialize(buffer: org.apache.spark.sql.expressions.MutableAggregationBuffer): Unit = {
buffer(0) = new scala.collection.mutable.ArrayBuffer[Double]()
}
def update(buffer: org.apache.spark.sql.expressions.MutableAggregationBuffer,input: org.apache.spark.sql.Row): Unit = {
var bufferVal=buffer.getAs[scala.collection.mutable.WrappedArray[Double]](0).toBuffer
bufferVal+=input.getAs[Double](0)
buffer(0) = bufferVal
}
def merge(buffer1: org.apache.spark.sql.expressions.MutableAggregationBuffer, buffer2: org.apache.spark.sql.Row): Unit = {
buffer1(0) = buffer1.getAs[scala.collection.mutable.ArrayBuffer[Double]](0) ++ buffer2.getAs[scala.collection.mutable.ArrayBuffer[Double]](0)
}
def evaluate(buffer: org.apache.spark.sql.Row): Any = {
var sortedWindow=buffer.getAs[scala.collection.mutable.WrappedArray[Double]](0).sorted.toBuffer
var windowSize=sortedWindow.size
if(windowSize%2==0){
var index=windowSize/2
(sortedWindow(index) + sortedWindow(index-1))/2
}else{
var index=(windowSize+1)/2 - 1
sortedWindow(index)
}
}
}
使用上述UDAF示例:
// Create an instance of UDAF MyMedian.
val mm = new MyMedian
var movingMedianDS = dataSet.withColumn("MovingMedian", mm(col("value")).over( Window.partitionBy("GroupId").rowsBetween(-10,10)) )
如何注册UDAF并在Spark应用程序中使用它?@Jacek//create mymedia object var winMed=new mymedia//Define window val wSpec1=window.partitionBy//在窗口df上应用中间值,带列(,winMed(col())。超过(wSpec1))