Spark在每次RDD迭代中找到上一个值

时间:2018-04-09 10:22:57

标签: scala apache-spark rdd spark-cassandra-connector

我跟随代码: -

val rdd = sc.cassandraTable("db", "table").select("id", "date", "gpsdt").where("id=? and date=? and gpsdt>? and gpsdt<?", entry(0), entry(1), entry(2) , entry(3))
val rddcopy = rdd.sortBy(row => row.get[String]("gpsdt"), false).zipWithIndex()
rddcopy.foreach { records =>
  {
    val previousRow = (records - 1)th row
    val currentRow = records
// Some calculation based on both rows 
    }
}

因此,Idea是在RDD的每次迭代中获得前一个\下一行。我想根据前一行中的值计算当前行的某些字段。谢谢,

1 个答案:

答案 0 :(得分:0)

编辑II:下面的误解是如何获得翻滚窗口语义,但需要滑动窗口。考虑到这是一个排序的RDD

import org.apache.spark.mllib.rdd.RDDFunctions._
sortedRDD.sliding(2)

应该做的伎俩。但请注意,这是使用DeveloperAPI。

或者你可以

val l = sortedRdd.zipWithIndex.map(kv => (kv._2, kv._1))
val r = sortedRdd.zipWithIndex.map(kv => (kv._2-1, kv._1))
val sliding = l.join(r)

rdd连接应该是内部连接(IIRC),从而丢弃元组将部分为空的边缘情况

OLD STUFF:

你如何识别前一行? RDD本身没有任何稳定的排序。如果你有一个递增密集密钥,你可以添加一个新列,以下面的方式计算得到if (k % 2 == 0) k / 2 else (k-1)/2这应该给你一个具有两个连续密钥相同值的密钥。然后你可以分组。

但重申在大多数情况下,对于RDD(取决于分区,数据源等),previous没有真正明智的概念。

编辑:所以现在你有一个zipWithIndex和你的集合中的订单,你可以做我上面提到的。所以现在你有RDD[(Int, YourData)]并且可以做

rdd.map( kv => if (kv._1 % 2 == 0) (kv._1 / 2, kv._2) else ( (kv._1 -1) /2, kv._2 ) ).groupByKey.foreach (/* your stuff here /*)

如果您在任何时候减少考虑使用reduceByKey而不是groupByKey().reduce