移动平均线

根据雇主的角色计算雇主的工资移动平均值:

val movAvg = sampleData.withColumn("movingAverage", avg(sampleData("Salary"))
             .over( Window.partitionBy("Role").rowsBetween(-1,1)) )
  • withColumn() 创建一个名为 movingAverage 的新列,在 Salary 列上执行 average
  • over() 用于定义窗口规范。
  • partitionBy() 对列 Role 上的数据进行分区
  • rowsBetween(start, end) 此函数定义要包含在窗口中的行。参数(startend)取数字输入,0 代表当前行,-1 代表前一行,1 代表下一行,依此类推。该函数包括 startend 之间的所有行,因此在该示例中,窗口中包括三行(-1,0,1)。
    scala> movAvg.show
+------+---------+------+------------------+
|  Name|     Role|Salary|     movingAverage|
+------+---------+------+------------------+
|   bob|Developer|125000|          116500.0|
|  mark|Developer|108000|139333.33333333334|
| peter|Developer|185000|130333.33333333333|
| simon|Developer| 98000|142333.33333333334|
|  eric|Developer|144000|117333.33333333333|
| henry|Developer|110000|          127000.0|
|  carl|   Tester| 70000|           67500.0|
|   jon|   Tester| 65000| 72333.33333333333|
| roman|   Tester| 82000|           74000.0|
|carlos|   Tester| 75000|           78500.0|
+------+---------+------+------------------+

如果当前行分别是第一行和最后一行,Spark 会自动忽略上一行和下一行。

在上面的示例中,第一行的 movingAverage 仅为当前行和下一行的平均值,因为前一行不存在。类似地,分区的最后一行(即第 6 行)是当前行和前一行的平均值,因为下一行不存在。