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中对每个组应用上述函数?