Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/11.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Algorithm Spark查找时间戳中的间隙_Algorithm_Scala_Apache Spark - Fatal编程技术网

Algorithm Spark查找时间戳中的间隙

Algorithm Spark查找时间戳中的间隙,algorithm,scala,apache-spark,Algorithm,Scala,Apache Spark,我有一对RDD,它由(Key,(Timestamp,Value))条目组成 读取数据时,条目按时间戳排序,因此RDD的每个分区都应按时间戳排序。我想做的是,找到每个键,两个连续时间戳之间的最大间隔 我考虑这个问题已经很长时间了,考虑到sparks提供的功能,我不知道如何实现。我看到的问题是:当我做一个简单的映射时,我丢失了订单信息,所以这是不可能的。在我看来,groupByKey也会失败,因为一个特定的键有太多的条目,尝试这样做会给我一个java.io.IOException:设备上没有剩余空间

我有一对RDD,它由(Key,(Timestamp,Value))条目组成

读取数据时,条目按时间戳排序,因此RDD的每个分区都应按时间戳排序。我想做的是,找到每个键,两个连续时间戳之间的最大间隔

我考虑这个问题已经很长时间了,考虑到sparks提供的功能,我不知道如何实现。我看到的问题是:当我做一个简单的映射时,我丢失了订单信息,所以这是不可能的。在我看来,groupByKey也会失败,因为一个特定的键有太多的条目,尝试这样做会给我一个
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你能给我指一种更合适的流行技术吗