Algorithm Spark查找时间戳中的间隙
我有一对RDD,它由(Key,(Timestamp,Value))条目组成 读取数据时,条目按时间戳排序,因此RDD的每个分区都应按时间戳排序。我想做的是,找到每个键,两个连续时间戳之间的最大间隔 我考虑这个问题已经很长时间了,考虑到sparks提供的功能,我不知道如何实现。我看到的问题是:当我做一个简单的映射时,我丢失了订单信息,所以这是不可能的。在我看来,groupByKey也会失败,因为一个特定的键有太多的条目,尝试这样做会给我一个Algorithm Spark查找时间戳中的间隙,algorithm,scala,apache-spark,Algorithm,Scala,Apache Spark,我有一对RDD,它由(Key,(Timestamp,Value))条目组成 读取数据时,条目按时间戳排序,因此RDD的每个分区都应按时间戳排序。我想做的是,找到每个键,两个连续时间戳之间的最大间隔 我考虑这个问题已经很长时间了,考虑到sparks提供的功能,我不知道如何实现。我看到的问题是:当我做一个简单的映射时,我丢失了订单信息,所以这是不可能的。在我看来,groupByKey也会失败,因为一个特定的键有太多的条目,尝试这样做会给我一个java.io.IOException:设备上没有剩余空间
java.io.IOException:设备上没有剩余空间
关于如何实现这一点的任何帮助都将非常有用。如您所建议的,可以使用数据帧和窗口函数。首先需要进口:
import org.apache.spark.sql.expressions.Window
import org.apache.spark.sql.functions.lag
下一个数据必须转换为数据帧
:
val df = rdd.mapValues(_._1).toDF("key", "timestamp")
为了能够使用lag
函数,我们需要一个窗口定义:
val keyTimestampWindow = Window.partitionBy("key").orderBy("timestamp")
可用于选择:
val withGap = df.withColumn(
"gap", $"timestamp" - lag("timestamp", 1).over(keyTimestampWindow)
)
最后,groupBy
和max
:
withGap.groupBy("key").max("gap")
按照第二条建议,您可以按键和时间戳进行排序
使用这样排列的数据,您可以通过按键滑动和缩小来找到每个键的最大间隙:
import org.apache.spark.mllib.rdd.RDDFunctions._
sorted.sliding(2).collect {
case Array((key1, val1), (key2, val2)) if key1 == key2 => (key1, val2 - val1)
}.reduceByKey(Math.max(_, _))
相同想法的另一个变体是首先重新分区和排序:
val partitionedAndSorted = rdd
.mapValues(_._1)
.repartitionAndSortWithinPartitions(
new org.apache.spark.HashPartitioner(rdd.partitions.size)
)
这样的数据可以转换
val lagged = partitionedAndSorted.mapPartitions(_.sliding(2).collect {
case Seq((key1, val1), (key2, val2)) if key1 == key2 => (key1, val2 - val1)
}, preservesPartitioning=true)
和reduceByKey
:
lagged.reduceByKey(Math.max(_, _))
根据建议,您可以使用DataFrame
和窗口函数。首先需要进口:
import org.apache.spark.sql.expressions.Window
import org.apache.spark.sql.functions.lag
下一个数据必须转换为数据帧:
val df = rdd.mapValues(_._1).toDF("key", "timestamp")
为了能够使用lag
函数,我们需要一个窗口定义:
val keyTimestampWindow = Window.partitionBy("key").orderBy("timestamp")
可用于选择:
val withGap = df.withColumn(
"gap", $"timestamp" - lag("timestamp", 1).over(keyTimestampWindow)
)
最后,groupBy
和max
:
withGap.groupBy("key").max("gap")
按照第二条建议,您可以按键和时间戳进行排序
使用这样排列的数据,您可以通过按键滑动和缩小来找到每个键的最大间隙:
import org.apache.spark.mllib.rdd.RDDFunctions._
sorted.sliding(2).collect {
case Array((key1, val1), (key2, val2)) if key1 == key2 => (key1, val2 - val1)
}.reduceByKey(Math.max(_, _))
相同想法的另一个变体是首先重新分区和排序:
val partitionedAndSorted = rdd
.mapValues(_._1)
.repartitionAndSortWithinPartitions(
new org.apache.spark.HashPartitioner(rdd.partitions.size)
)
这样的数据可以转换
val lagged = partitionedAndSorted.mapPartitions(_.sliding(2).collect {
case Seq((key1, val1), (key2, val2)) if key1 == key2 => (key1, val2 - val1)
}, preservesPartitioning=true)
和reduceByKey
:
lagged.reduceByKey(Math.max(_, _))
按键和时间戳排序。然后是数据的线性传递。我可能不会在Spark中这样做。本质上是线性过程的东西不适合Spark。您可能可以转换为DF并使用windows,但我从来没有这样做过。看relevant@TheArchetypalPaul你能给我指出一种更合适的流行技术吗?按键和时间戳排序。然后是数据的线性传递。我可能不会在Spark中这样做。本质上是线性过程的东西不适合Spark。您可能可以转换为DF并使用windows,但我从来没有这样做过。看relevant@TheArchetypalPaul你能给我指一种更合适的流行技术吗