我的输入如下。
输入:
key,A,1
key,A,2
key,A,3
key,A,4
key,A,5
key,A,6
我正在使用以下代码实现我的第一个输出
val finalOutputRDD = AddDeletesRDD.map(x => ( x.split("~").slice(0, endOfKeyPosition).mkString(","), x.split("~").slice(0, 1).mkString(",") + "~" + x.split("~").slice(3, 4).mkString(",") ))
.sortByKey()
.reduceByKey((key, value) => key +"|" + value)
.map(records => records._1 + "," + records._2)
finalOutputRDD.saveAsTextFile(deltaFileLocation)
我的输出是:
key,A~1|A~2|A~3|A~4|A~5|A~6|
现在,我想动态传递一个值(例如3),我想要以下输出:
key,A~1|A~2|A~3
key,A~4|A~5|A~6
答案 0 :(得分:0)
我认为您必须对密钥进行分组,然后生成作为密钥加整数的新密钥,然后对这些密钥进行重新分组,最后丢弃生成的整数。像这样:
def reduceByKeyMaxN[K, V](rdd: RDD[(K, V)], n: Int, f: (V, V) => V): RDD[(K, V)] = {
rdd
.groupByKey()
.flatMap { case (k, vs) =>
vs.zipWithIndex.map{ case (v, i) => ((k, i / n), v) }
}
.reduceByKey(f)
.map { case ((k, _), v) => (k, v) }
}
然后,您可以将对代码中对reduceByKey
的调用替换为对此方法的调用。
答案 1 :(得分:0)
如果我正确理解了您的要求,这是一种方法:
reduceByKey
以生成(key,Seq(values))的RDD flatMap
使用grouped(n)
将结果数据集划分为(键,值)的分组列表reduce
放入RDD(键,分组值字符串)以下是示例代码,其中的数据集更为通用:
val rdd = sc.parallelize(Seq(
("k1", "A", 1),
("k1", "A", 2),
("k1", "A", 3),
("k1", "A", 4),
("k1", "A", 5),
("k1", "A", 6),
("k2", "B", 1),
("k2", "B", 2),
("k2", "B", 3),
("k2", "B", 4)
))
val n = 3
rdd.map{ case (k, s, i) => (k, Seq(s + "~" + i)) }.
reduceByKey( _ ++ _ ).
flatMap{ case (k, vs) => vs.map(i => (k, i)).grouped(n) }.
map( _.reduce( (acc, x) => (acc._1, (acc._2 + "|" + x._2)) ) ).
collect
// res1: Array[(String, String)] =
// Array((k1,A~1|A~2|A~3), (k1,A~4|A~5|A~6), (k2,B~1|B~2|B~3), (k2,B~4))