理解一个窗口函数的例子

Posted

技术标签:

【中文标题】理解一个窗口函数的例子【英文标题】:Understanding an example of window function 【发布时间】:2021-04-02 19:14:53 【问题描述】:

我正在运行代码脚本以获得以下结果。代码如下所示。我不明白为什么我得到了xyz1 列,如图所示。比如xyz1的第一行为什么是0。根据windows函数,它对应的组应该是前两行,但是为什么F.count(F.col("xyz")).over(w)在这里得到0

import pyspark
from pyspark.sql import SparkSession
from pyspark.sql.window import Window
from pyspark.sql import functions as F
spark = SparkSession.builder.appName('SparkByExamples.com').getOrCreate()
list=([1,5,4],
    [1,5,None],
    [1,5,1],
    [1,5,4],
    [2,5,1],
    [2,5,2],
    [2,5,None],
    [2,5,None],
     [2,5,4])
df=spark.createDataFrame(list,['I_id','p_id','xyz'])
w= Window().partitionBy("I_id","p_id").orderBy(F.col("xyz"))
df.withColumn("xyz1",F.count(F.col("xyz")).over(w)).show()

【问题讨论】:

【参考方案1】:

请注意,count 仅计算非空项,并且分组仅由 partitionBy 子句定义,而不是 orderBy 子句。

指定排序列时,默认窗口范围为(根据docs)

(rangeFrame, unboundedPreceding, currentRow)

所以你的窗口定义实际上是

w = (Window().partitionBy("I_id","p_id")
             .orderBy(F.col("xyz"))
             .rangeBetween(Window.unboundedPreceding, Window.currentRow)
    )

所以窗口只包含当前行中从xyz = -infinityxyz 的值的行。这就是第一行计数为零的原因,因为它计算了从xyz = -infinityxyz = null 的非空项,即数据帧的前两行。

对于xyz = 2所在的行,计数包括从xyz = -infinityxyz = 2的非空项,即前四行。这就是计数为 2 的原因,因为非空项是 1 和 2。

【讨论】:

感谢您的解释,对于此表中的第八行(1,5,4,3),在我看来,该行的 xyz1 列值应该是 2 而不是 3,因为它之前只有一个非空值行。 该窗口包含直到当前行的值。在这种情况下,所有 xyz

以上是关于理解一个窗口函数的例子的主要内容,如果未能解决你的问题,请参考以下文章

SQL Server 中的窗口函数(2012 新函数)

结合实例来分析SQL的窗口函数

使用具有不同 order by 子句的 postgres 窗口函数

Hive-窗口函数/开窗函数(重点理解~~~)

hive关于窗口函数的使用

Hive之窗口函数