我正在尝试使用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_row_in_window
是当前窗口中包含的行数,
sum_values_in_windows
是当前窗口中包含的值的总和。
我一直在尝试使用滑动功能或使用sql api,但对我来说还不太清楚,考虑到我是Spark / scala新手,这是解决此问题的最佳解决方案。
答案 0 :(得分:1)
这是窗口功能的完美应用程序。通过使用rangeBetween
,您可以将滑动窗口设置为20s。请注意,在下面的示例中,未指定分区(没有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|
+-------+-----+-----------------+--------------------+