Scala 填补timeseries Spark中的空白

Scala 填补timeseries Spark中的空白,scala,apache-spark,apache-spark-sql,time-series,Scala,Apache Spark,Apache Spark Sql,Time Series,我在处理时间序列数据时遇到问题。由于电源故障,数据集中缺少一些时间戳。我需要通过添加行来填补这个空白,然后,我可以插值缺少的值 输入数据: periodstart usage --------------------------------- 2015-09-11 02:15 23000 2015-09-11 03:15 23344 2015-09-11 03:30 23283 2015-0

我在处理时间序列数据时遇到问题。由于电源故障,数据集中缺少一些时间戳。我需要通过添加行来填补这个空白,然后,我可以插值缺少的值

输入数据:

periodstart                usage
---------------------------------
2015-09-11 02:15           23000   
2015-09-11 03:15           23344   
2015-09-11 03:30           23283  
2015-09-11 03:45           23786   
2015-09-11 04:00           25039
想要的输出:

periodstart                usage
---------------------------------
2015-09-11 02:15           23000   
2015-09-11 02:30           0   
2015-09-11 02:45           0   
2015-09-11 03:00           0   
2015-09-11 03:15           23344   
2015-09-11 03:30           23283   
2015-09-11 03:45           23786   
2015-09-11 04:00           25039  
现在,我已经通过dataset foreach函数中的while循环解决了这个问题。问题是,我必须先将数据集收集到驱动程序,然后才能执行while循环。所以这不是Spark的正确方式

有人能给我一个更好的解决方案吗

这是我的代码:

MissingMeasurementsDS.collect().foreach(row => {
  // empty list for new generated measurements
  val output = ListBuffer.empty[Measurement]
  // Missing measurements
  val missingMeasurements = row.getAs[Int]("missingmeasurements")
  val lastTimestamp = row.getAs[Timestamp]("previousperiodstart")
  //Generate missing timestamps
  var i = 1
  while (i <= missingMeasurements) {
    //Increment timestamp with 15 minutes (900000 milliseconds)
    val newTimestamp = lastTimestamp.getTime + (900000 * i)
    output += Measurement(new Timestamp(newTimestamp), 0))
    i += 1
  }
  //Join interpolated measurements with correct measurements
  completeMeasurementsDS.join(output.toDS())
})
completeMeasurementsDS.show()
println("OutputDF count = " + completeMeasurementsDS.count())
如果输入数据帧具有以下结构:

根 |-periodstart:timestamp nullable=true |-用法:long nullable=true 斯卡拉

确定最小/最大值:

val (minp, maxp) = df
  .select(min($"periodstart").cast("bigint"), max($"periodstart".cast("bigint")))
  .as[(Long, Long)]
  .first
设置步骤,例如15分钟:

val step: Long = 15 * 60
生成参考范围:

val reference = spark
  .range((minp / step) * step, ((maxp / step) + 1) * step, step)
  .select($"id".cast("timestamp").alias("periodstart"))
连接并填补空白:

reference.join(df, Seq("periodstart"), "leftouter").na.fill(0, Seq("usage"))
蟒蛇

类似地,Pypark:

从pyspark.sql.functions导入列,最小值作为最小值,最大值作为最大值_ 步长=15*60 minp,maxp=df.select 最小周期开始.castlong,最大周期开始.castlong 第一 参考=spark.range 最小/步长*步长,最大/步长+1*步长,步长 。选择colid.casttimestamp.alias开始 reference.joindf,[periodstart],leftouter
RHeutz您可以在此处粘贴用于添加缺失值的代码段吗?仅供参考,您需要执行类似于d2=reference.joindf、[periodstart]的操作,在末尾执行leftouter以捕获输出注意,如果您有一个分区数据集作为输入,并希望填补每个分区的空白,您还可以添加df.selectpartitionByColumns:*.distinct.crossJoinreference.join。。。。这将确保丢失的periodstart值将分配给每个分区。@Timur您的建议是否也适用于这种情况:?@Timur您能谈谈您的评论吗?看起来也像scala语法。什么是…的最终加入?我们如何在pyspark df中对每个组应用上述函数?