Python Pyspark在最后N个数据点上的结构化流媒体窗口(移动平均)

Python Pyspark在最后N个数据点上的结构化流媒体窗口(移动平均),python,apache-spark,pyspark,spark-streaming,Python,Apache Spark,Pyspark,Spark Streaming,我使用Pyspark Structured Streaming 2.4.4阅读了卡夫卡主题中的几个数据帧。我想在数据帧中添加一些新的列,这些列主要基于过去N个数据点的窗口计算(例如:过去20个数据点的移动平均值),并且在交付新数据点时,应立即计算MA_20的相应值 数据可能如下所示: 时间戳| VIX 2020-01-22 10:20:32 | 13.05 2020-01-22 10:25:31 | 14.35 2020-01-23 09:00:20 | 14.12 值得一提的是,从周一到周五

我使用Pyspark Structured Streaming 2.4.4阅读了卡夫卡主题中的几个数据帧。我想在数据帧中添加一些新的列,这些列主要基于过去N个数据点的窗口计算(例如:过去20个数据点的移动平均值),并且在交付新数据点时,应立即计算MA_20的相应值

数据可能如下所示: 时间戳| VIX

2020-01-22 10:20:32 | 13.05
2020-01-22 10:25:31 | 14.35
2020-01-23 09:00:20 | 14.12
值得一提的是,从周一到周五,每天8个小时都会收到数据。 因此,周一上午计算的移动平均线应该包括周五的数据

我尝试了不同的方法,但仍然无法实现我想要的

windows = df_vix \
    .withWatermark("Timestamp", "100 minutes") \
    .groupBy(F.window("Timestamp", "100 minute", "5 minute")) \

aggregatedDF = windows.agg(F.avg("VIX"))

以前的代码计算了MA,但它会考虑星期五的数据迟,所以将被排除在外。比最后100分钟更好的应该是最后20分(间隔5分钟)

我认为我可以使用rowsBetween或rangeBetween,但在流数据帧中,窗口不能应用于非时间戳列(F.col('timestamp')。cast('long'))

但另一方面,无法在rowsBetween()中使用rowsBetween(-minutes(20),0)throws指定间隔:未定义分钟(sql.functions中没有此类函数)

我找到了另一种方法,但它也不适用于流式数据帧。不知道为什么会引发“流式数据帧不支持非基于时间的窗口”错误(df_vix.Timestamp为Timestamp类型)

我不知道我还能用什么来计算简单的移动平均线。在Pyspark中似乎不可能做到这一点。。。也许更好的解决方案是在每次新数据将整个Spark数据帧提交给Pandas时进行转换,并计算Pandas中的所有内容(或者在Pandas中添加新行并计算MA)

我认为,随着新数据的提交,创建新功能是结构化流媒体的主要目的,但由于Pyspark不适合这种情况,我正在考虑放弃Pyspark,转而使用Pandas

编辑

尽管df_vix.Timestamp的类型为:“Timestamp”,但以下操作也不起作用,但它仍会抛出“流式数据帧不支持非基于时间的窗口”错误

w = Window.orderBy(df_vix.Timestamp).rowsBetween(-20, -1)
aggregatedDF = df_vix.withColumn("MA", F.avg("VIX").over(w))

你看过事件时间的操作吗<代码>窗口(时间戳,“10分钟”,“5分钟”)将为您提供每5分钟10分钟的数据帧,您可以在该数据帧上进行聚合,包括移动平均值。

这在多个设备发送数据的情况下不起作用,并且一些设备稍微落后于当前时间,窗口功能将忽略落后5分钟的设备数据。
df.createOrReplaceTempView("df_vix")

df_vix.createOrReplaceTempView("df_vix")
aggregatedDF = spark.sql(
    """SELECT *, mean(VIX) OVER (
        ORDER BY CAST(df_vix.Timestamp AS timestamp)
        RANGE BETWEEN INTERVAL 100 MINUTES PRECEDING AND CURRENT ROW
     ) AS mean FROM df_vix""")
w = Window.orderBy(df_vix.Timestamp).rowsBetween(-20, -1)
aggregatedDF = df_vix.withColumn("MA", F.avg("VIX").over(w))