在Spark DataFrame中创建新列,其中包含来自另一列的先前值的diff

时间:2016-03-17 21:21:34

标签: scala apache-spark dataframe apache-spark-sql

我有一个数据框,其中有一个带有纪元秒的列 除此之外,我想添加一个列,其中包含当前时间值和上一个时间值之间的差异 - 换句话说,基于时间戳列的数据帧中最后一行的时间差异。

我如何根据之前的值添加这样的列?

我正在使用Scala API。

3 个答案:

答案 0 :(得分:1)

您可以使用spark的滞后功能来实现这一目标

val df = sc.parallelize(Seq(
  (1540000005),
  (1540000004),
  (1540000003),
  (1540000002))).toDF("epoch")

// a lag function needs to have a window
val w = org.apache.spark.sql.expressions.Window.orderBy("epoch")  

import org.apache.spark.sql.functions.lag
// create a column epoch_lag_1 which is the epoch column with an offset of 1 and default value 0
val dfWithLag = df.withColumn("epoch_lag_1", lag("epoch", 1, 0).over(w))

// calculate the diff between epoch and epoch_lag_1
val dfWithDiff = dfWithLag.withColumn("diff", dfWithLag("epoch") - dfWithLag("epoch_lag_1"))

这应该导致

dfWithDiff.show 


+----------+-----------+----------+                                                                                     
|     epoch|epoch_lag_1|      diff|                                                                                     
+----------+-----------+----------+                                                                                     
|1540000002|          0|1540000002|                                                                                     
|1540000003| 1540000002|         1|                                                                                     
|1540000004| 1540000003|         1|                                                                                     
|1540000005| 1540000004|         1|                                                                                     
+----------+-----------+----------+ 

答案 1 :(得分:0)

这会做你想要的,虽然指出它可能有点慢。

df.printSchema
root
 |-- ts: long (nullable = false)

df.join(
  df.toDF("ts2"),
  $"ts2" < $"ts",
  "left_outer"
).groupBy($"ts").agg(max($"ts2") as "prev").select($"ts", $"ts" - $"prev" as "diff").show

我们甚至可以使用我的拉皮条DataFrame-ified zipWithIndex来改善它。假设我们使用它来添加id列,您可以这样做:

df.join(
  df.toDF("prev_id", "prev_ts"), 
  $"id" === $"prev_id" + 1, 
  "left_outer"
).select($"ts", $"ts" - $"prev_ts" as "diff").show

答案 2 :(得分:0)

我不知道斯卡拉。但是如何使用lag生成滞后列,然后从另一列中减去一列?