我有一个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()
这是结果:
这是我的结果,但我发现所有数据都被收集到一个分区,然后我使用了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|
+-----+------+----------+
并且数据在多个分区中!
答案 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
使用数据集开头/结尾所需的记录数。