Java 如何在ApacheSpark中聚合timeseries数据
我有一个数据集,其中包含保存时间段(以纳秒表示:两个长,一个用于开始,一个用于结束)和测量值的记录列表。我需要创建新的聚合数据集,该数据集只保存值更改的时段。例如:Java 如何在ApacheSpark中聚合timeseries数据,java,apache-spark,time-series,Java,Apache Spark,Time Series,我有一个数据集,其中包含保存时间段(以纳秒表示:两个长,一个用于开始,一个用于结束)和测量值的记录列表。我需要创建新的聚合数据集,该数据集只保存值更改的时段。例如: input dataset: +-----+-----+-----+ |start|end |value| +-----+-----+-----+ |123 |124 |1 | |124 |128 |1 | |128 |300 |2 |
input dataset:
+-----+-----+-----+
|start|end |value|
+-----+-----+-----+
|123 |124 |1 |
|124 |128 |1 |
|128 |300 |2 |
|300 |400 |2 |
|400 |500 |3 |
result dataset:
+-----+-----+-----+
|start|end |value|
+-----+-----+-----+
|123 |128 |1 |
|128 |400 |2 |
|400 |500 |3 |
我知道如何在小数据集上实现这一点,但不知道如何使用mapreduce范式和ApacheSpark
您能告诉我如何在java Apache Spark中实现这一点吗?一种方法是将您的问题表述为“对于每个不同的值,找到该值的所有相邻时间范围并合并它们”。了解了这一点后,您可以在值上使用
groupBy
,为每个值创建一个start
和end
列表。然后,您可以使用自定义函数将它们向下折叠为连续的时间范围
在极端情况下,如果在数据集上使用仅限磁盘的持久性级别,唯一的要求是能够将一行start\u end
s装入内存。对于大多数集群,这种方法的上限为每个值的start\u end
对的gb
下面是一个示例实现(根据请求使用Java API-Scala会少一点繁琐):
请注意,这些值不符合顺序。这是因为spark已经对数据集进行了分区并处理了值行,而您没有告诉它为行排序分配任何意义。如果您需要时间或值排序的输出,您当然可以按照通常的方式对其进行排序。这种方式似乎很简单。如果使用groupBy查找最小值和最大值,然后合并数据集
// df is original dataset
Dataset<Row> df_start = df.groupBy("value").min("start").withColumnRenamed("min(start)", "start").withColumnRenamed("value", "value_start");
Dataset<Row> df_end = df.groupBy("value").max("end").withColumnRenamed("max(end)", "end").withColumnRenamed("value", "value_end");
Dataset<Row> df_combined = df_start.join(df_end, df_start.col("value_start").equalTo(df_end.col("value_end"))).drop("value_end").withColumnRenamed("value_start", "value").orderBy("value");
df_combined.show(false);
+-----+-----+---+
|value|start|end|
+-----+-----+---+
|1 |123 |128|
|2 |128 |400|
|3 |400 |700|
+-----+-----+---+
//df是原始数据集
数据集df_start=df.groupBy(“value”).min(“start”)。使用列重命名(“min(start)”,“start”)。使用列重命名(“value”,“value_start”);
数据集df_end=df.groupBy(“value”).max(“end”)。带列重命名(“max(end)”,“end”)。带列重命名(“value”,“value_end”);
数据集df_combined=df_start.join(df_end,df_start.col(“value_start”).equalTo(df_end.col(“value_end”)))).drop(“value_end”).withcolumn重命名(“value_start”,“value”).orderBy(“value”);
df_组合显示(假);
+-----+-----+---+
|值|开始|结束|
+-----+-----+---+
|1 |123 |128|
|2 |128 |400|
|3 |400 |700|
+-----+-----+---+
使用窗口函数,例如滞后获取最后一个值,然后根据当前值和最后一个值是否不同过滤数据集。如果数据集的另一行为130 200 1,输出将是什么我们可以使用窗口函数,但spark不是处理时间序列数据的最佳方法,如果您没有选择,请查看此项
+-----+-----+---+
|value|start|end|
+-----+-----+---+
| 1| 123|128|
| 3| 400|700|
| 2| 128|400|
+-----+-----+---+
// df is original dataset
Dataset<Row> df_start = df.groupBy("value").min("start").withColumnRenamed("min(start)", "start").withColumnRenamed("value", "value_start");
Dataset<Row> df_end = df.groupBy("value").max("end").withColumnRenamed("max(end)", "end").withColumnRenamed("value", "value_end");
Dataset<Row> df_combined = df_start.join(df_end, df_start.col("value_start").equalTo(df_end.col("value_end"))).drop("value_end").withColumnRenamed("value_start", "value").orderBy("value");
df_combined.show(false);
+-----+-----+---+
|value|start|end|
+-----+-----+---+
|1 |123 |128|
|2 |128 |400|
|3 |400 |700|
+-----+-----+---+