在pyspark中计算窗口上的列百分比

dgiusagp  于 2021-05-27  发布在  Spark
关注(0)|答案(1)|浏览(889)

我有一个用例,需要在滑动窗口上计算一个列的百分位数(我们称之为x)。所以窗口定义是按时间顺序的-过去120天:

days = lambda i: i * 86400
w = Window.partitionBy("entityId").orderBy(F.col("trn_time").cast("long").asc())
    .rangeBetween(-days(120),-days(1))

我想使用approxquantile,但它是一个Dataframe函数。第二种选择是使用:

percent_rank().over(w)

但是我需要按数值列(x)对窗口进行排序,我想对其进行百分位数排序,并且窗口已经按时间排序了。当我尝试在窗口定义中将x添加到orderby时:

w = Window.partitionBy("entityId").orderBy(F.col("trn_time").cast("long").asc(),"X")\
    .rangeBetween(-days(120),-days(1))

我得到以下错误:“具有值边界的范围窗口框架不能用于具有多个order by表达式的窗口规范”
我如何实现这个逻辑?

j9per5c4

j9per5c41#

您需要将其编写为内置sql表达式:


# This is like a UDF

magic_percentile = F.expr('percentile_approx(X, 0.5)')

# Define your window

w = Window.partitionBy("entityId").orderBy(F.col("trn_time").cast("long").asc())
    .rangeBetween(-days(120),-days(1))

df = df.withColumn("rolling_percentile", magic_percentile.over(w))

在计算百分位数时,您总是将值从最小到最大排序,然后取分位数值,因此窗口中的值将被排序。
参考:Pypark groupby中的中位数/分位数

相关问题