如何在窗口scala / spark

时间:2017-07-24 06:05:45

标签: apache-spark apache-spark-sql window-functions

我有一个DataFrame,有两个column,"索引"和"值",我想得到" delayValues"基于列"值",这是我的代码:

 val arr = Array(1,4,3,2,5,7,3,5,4,18)
    val input=new ArrayBuffer[(Int,Int)]()
    for(i<-0 until 10){
      input.append((i,arr(i)))
    }
    val window=Window.rowsBetween(-2,0)
    val df = sc.parallelize(input, 4).toDF("index","values")
    df.withColumn("valueDealy",first(col("values")).over(window)).show()

这是结果:

enter image description here

这是我的结果,但我发现所有数据都被收集到一个分区,然后我使用了partitionBy函数,这是我改变的代码:

val arr = Array(1,4,3,2,5,7,3,5,4,18)
    val input=new ArrayBuffer[(Int,Int)]()
    for(i<-0 until 10){
      input.append((i,arr(i)))
    }
    val window=Window.orderBy(col("index")).partitionBy(col("index")).rowsBetween(-2,0)
    val df = sc.parallelize(input, 4).toDF("index","values")
    df.withColumn("valueDealy",first(col("values")).over(window)).show()

结果是:

+-----+------+----------+
|index|values|valueDealy|
+-----+------+----------+
|    0|     1|         1|
|    3|     2|         2|
|    7|     5|         5|
|    9|    18|        18|
|    4|     5|         5|
|    6|     3|         3|
|    5|     7|         7|
|    2|     3|         3|
|    1|     4|         4|
|    8|     4|         4|
+-----+------+----------+

当我使用partitionBy时出现错误结果,我该怎么办?谢谢!

我的输出除外

        +-----+------+----------+
        |index|values|valueDealy|
        +-----+------+----------+
        |    0|     1|         1|
        |    1|     4|         1|
        |    2|     3|         1|
        |    3|     2|         4|
        |    4|     5|         3|
        |    5|     7|         2|
        |    6|     3|         5|
        |    7|     5|         7|
        |    8|     4|         3|
        |    9|    18|         5|
        +-----+------+----------+

并且数据在多个分区中!

1 个答案:

答案 0 :(得分:0)

通常,没有有效的解决方案可以直接用Spark SQL表示。就个人而言,在使用Scala时,我会使用mllib函数:

import org.apache.spark.mllib.rdd.RDDFunctions._
import org.apache.spark.sql.types._
import org.apache.spark.sql.Row

val n = 2
spark.createDataFrame(
  df.rdd.sliding(n + 1).map { xs  => Row(xs(0), xs(n)) },
  StructType(Seq(
    StructField("delay", df.schema), StructField("current", df.schema))))

但如果您的数据集包含连续的ID,您还可以join

df.alias("current").join(
  df.withColumn("index", $"index" - n).alias("previous"), Seq("index"))

请注意,两个解决方案可能需要在系列的开头/结尾进行一些更正。使用join,您可以使用outer加入,sliding可以union使用数据集开头/结尾所需的记录数。