模拟滞后函数 - Spark结构化流媒体

时间:2018-02-10 21:30:29

标签: scala apache-spark pyspark spark-structured-streaming

我正在使用Spark Structured Streaming来分析传感器数据,并且需要根据传感器之前的时间戳执行计算。我的传入数据流有三列:sensor_id,timestamp和temp。我需要添加第四列,即传感器上一个时间戳,以便我可以计算每个传感器的数据点之间的时间。

使用滞后函数和按sensor_id分组的传统批处理很容易。在流媒体情况下处理此问题的最佳方法是什么?

例如,如果我的流数据框看起来像这样:

+----------+-----------+------+
| SensorId | Timestamp | Temp |
+----------+-----------+------+
|     1800 |        34 |   23 |
|      500 |        36 |   54 |
|     1800 |        45 |   23 |
|      500 |        60 |   54 |
|     1800 |        78 |   23 |
+----------+-----------+------+

我想要这样的事情:

+----------+-----------+------+---------+
| SensorId | Timestamp | Temp | Prev_ts |
+----------+-----------+------+---------+
|     1800 |        34 |   23 |      21 |
|      500 |        36 |   54 |      27 |
|     1800 |        45 |   23 |      34 |
|      500 |        60 |   54 |      36 |
|     1800 |        78 |   23 |      45 |
+----------+-----------+------+---------+

如果我尝试

test = filteredData.withColumn("prev_ts", lag("ts").over(Window.partitionBy("sensor_id").orderBy("ts")))

我得到AnalysisException: 'Non-time-based windows are not supported on streaming DataFrames/Datasets

我可以将每个传感器的先前时间戳保存在我可以引用的数据结构中,然后使用每个新时间戳进行更新吗?

1 个答案:

答案 0 :(得分:-3)

没有必要"模拟"任何东西。标准窗口函数可与结构化流媒体一起使用。

s = spark.readStream.
   ...
   load()

s.withColumn("prev_ts", lag("Temp").over(
  Window.partitionBy("SensorId").orderBy("Timestamp")
)