rangeBetween,前一行为负值

时间:2019-05-24 06:49:05

标签: python apache-spark pyspark apache-spark-sql

我想使用一个窗口来计算当前结果之前的最后5个结果的平均值。

例如,如果我有一个带有结果的数据框,则mean_last_5如下:

   Result    Mean_last_5
1. 4         NaN
2. 2         NaN
3. 6         NaN
4. 3         NaN
5. 2         NaN
6. 6         3.4
7. 3         3.8

第六行的计算公式为:(4+2+6+3+2)/5 = 3.4

所以用熊猫的话来说,我将滚动窗口设置为5,偏移为1。

使用PySpark我只是不知道该怎么做。当前代码:

def mean_last_5(df):
    window = Window.partitionBy('Id').orderBy('year').rangeBetween(Window.currentRow-5, Window.currentRow)

    return df.withColumn('mean_last_5', sf.avg('result').over(window))

错误:

由于数据类型不匹配而无法解析:具有值边界的范围窗框不能在具有多个按表达式顺序的窗口规范中使用:

2 个答案:

答案 0 :(得分:1)

由于您不关心行中的值,仅关心当前行的偏移量,因此应使用rowsBetween而不是rangeBetween。此处说明了区别:What is the difference between rowsBetween and rangeBetween?

请注意,对于rowsBetween,两个值都包含在内,因此要获取前5行(不包括当前行)的滚动平均值,您需要将窗口定义为:

window = Window.partitionBy('Id').orderBy('year').rowsBetween(Window.currentRow-5, Window.currentRow-1)

或类似地:

window = Window.partitionBy('Id').orderBy('year').rowsBetween(-5, -1)

然后像以前一样使用它:

df.withColumn('mean_last_5', avg('result').over(window))

答案 1 :(得分:0)

尝试一下:

def mean_last_5(df):
    window = Window.partitionBy('Id').orderBy('year').rangeBetween(-1, -6)

    return df.withColumn('mean_last_5', sf.avg('result').over(window))

我输入0是因为我想要当前行,输入-5是因为我希望前5位包含实际结果。