带有scala和spark的时间序列。滚动窗口

带有scala和spark的时间序列。滚动窗口,scala,apache-spark,time-series,window-functions,Scala,Apache Spark,Time Series,Window Functions,我正在尝试使用Scala和spark进行以下练习 给定一个包含两列的文件:以秒为单位的时间和一个值 例如: |---------------------|------------------| | seconds | value | |---------------------|------------------| | 225 | 1,5 | | 245 |

我正在尝试使用Scala和spark进行以下练习

给定一个包含两列的文件:以秒为单位的时间和一个值

例如:

|---------------------|------------------|
|     seconds         |     value        |
|---------------------|------------------|
|          225        |         1,5      |
|          245        |         0,5      |
|          300        |         2,4      |
|          319        |         1,2      |
|          320        |         4,6      |
|---------------------|------------------|
给定一个用于滚动窗口的值
V
,应创建此输出:

V=20的示例

|--------------|---------|--------------------|----------------------|
|     seconds  |  value  |  num_row_in_window |sum_values_in_windows |
|--------------|---------|--------------------|----------------------|
|       225    |    1,5  |          1         |          1,5         |
|       245    |    0,5  |          2         |           2          |
|       300    |    2,4  |          1         |          2,4         |
|       319    |    1,2  |          2         |          3,6         |
|       320    |    4,6  |          3         |          8,2         |
|--------------|---------|--------------------|----------------------|
num\u row\u in\u window
是当前窗口中包含的行数,并且
sum\u values\u in\u windows
是当前窗口中包含的值的总和


我一直在尝试使用滑动函数或使用sql api,但考虑到我是spark/scala新手,我有点不清楚解决这个问题的最佳解决方案是什么。

这是一个完美的窗口函数应用程序。通过使用
rangeBetween
可以将滑动窗口设置为20秒。请注意,在下面的示例中,没有指定分区(no
partitionBy
)。如果没有分区,此代码将无法扩展:

import ss.implicits._

val df = Seq(
  (225, 1.5),
  (245, 0.5),
  (300, 2.4),
  (319, 1.2),
  (320, 4.6)
).toDF("seconds", "value")

val window = Window.orderBy($"seconds").rangeBetween(-20L, 0L) // add partitioning here

df
  .withColumn("num_row_in_window", sum(lit(1)).over(window))
  .withColumn("sum_values_in_window", sum($"value").over(window))
  .show()

+-------+-----+-----------------+--------------------+
|seconds|value|num_row_in_window|sum_values_in_window|
+-------+-----+-----------------+--------------------+
|    225|  1.5|                1|                 1.5|
|    245|  0.5|                2|                 2.0|
|    300|  2.4|                1|                 2.4|
|    319|  1.2|                2|                 3.6| 
|    320|  4.6|                3|                 8.2|
+-------+-----+-----------------+--------------------+

这是一个完美的窗口函数应用程序。通过使用
rangeBetween
可以将滑动窗口设置为20秒。请注意,在下面的示例中,没有指定分区(no
partitionBy
)。如果没有分区,此代码将无法扩展:

import ss.implicits._

val df = Seq(
  (225, 1.5),
  (245, 0.5),
  (300, 2.4),
  (319, 1.2),
  (320, 4.6)
).toDF("seconds", "value")

val window = Window.orderBy($"seconds").rangeBetween(-20L, 0L) // add partitioning here

df
  .withColumn("num_row_in_window", sum(lit(1)).over(window))
  .withColumn("sum_values_in_window", sum($"value").over(window))
  .show()

+-------+-----+-----------------+--------------------+
|seconds|value|num_row_in_window|sum_values_in_window|
+-------+-----+-----------------+--------------------+
|    225|  1.5|                1|                 1.5|
|    245|  0.5|                2|                 2.0|
|    300|  2.4|                1|                 2.4|
|    319|  1.2|                2|                 3.6| 
|    320|  4.6|                3|                 8.2|
+-------+-----+-----------------+--------------------+

如果秒列中存在重复值,是否有方法仅获取当前行的值?假设有两行,秒=300,RangeEnter会认为它们是同一窗口的一部分。有没有办法不去看,也就是说,现在的那一排@拉斐尔-roth@user2697881不知道你的意思,但我会在计算滚动和之前删除重复项。如何在计算滚动和之后删除第一行。一般来说,在我计算了每N行的滚动和之后,如何删除前N-1行?如果秒列中有重复的值,是否有方法仅获取当前行的值?假设有两行,秒=300,RangeEnter会认为它们是同一窗口的一部分。有没有办法不去看,也就是说,现在的那一排@拉斐尔-roth@user2697881不知道你的意思,但我会在计算滚动和之前删除重复项。如何在计算滚动和之后删除第一行。通常,在我计算每N行的滚动和之后,如何删除前N-1行?