【问题标题】:rangeBetween with negative values for previous rowsrangeBetween 与前一行的负值
【发布时间】:2019-10-10 17:40:50
【问题描述】:

我想使用一个窗口来计算当前结果之前最后 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

第 6 行将计算为:(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))

错误:

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

【问题讨论】:

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


    【解决方案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))
    

    【讨论】:

      【解决方案2】:

      试试这个:

      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 个包括实际结果。

      【讨论】:

      • 请注意,从问题示例中,当前行应该在计算中使用。
      猜你喜欢
      • 2021-04-10
      • 2020-04-21
      • 1970-01-01
      • 2019-02-01
      • 1970-01-01
      • 2011-03-01
      • 2020-05-03
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多