Scala 通过反转groupby(即,对其中的每个序列重复标题),火花展平序列

Scala 通过反转groupby(即,对其中的每个序列重复标题),火花展平序列,scala,group-by,apache-spark,seq,Scala,Group By,Apache Spark,Seq,我们有一个RDD,格式如下: org.apache.spark.rdd.RDD[((BigInt, String), Seq[(BigInt, Int)])] 我们要做的是将它展平到一个由制表符分隔的字符串组成的列表中,并用saveAsText文件保存。至于展平,我的意思是对其Seq中的每个项重复groupby元组(BigInt,String) 所以数据看起来像 ((x1,x2), ((y1.1,y1.2), (y2.1, y2.2) .... )) 。。。最终会看起来像 x1 x2

我们有一个RDD,格式如下:

org.apache.spark.rdd.RDD[((BigInt, String), Seq[(BigInt, Int)])]
我们要做的是将它展平到一个由制表符分隔的字符串组成的列表中,并用saveAsText文件保存。至于展平,我的意思是对其Seq中的每个项重复groupby元组(BigInt,String)

所以数据看起来像

((x1,x2), ((y1.1,y1.2), (y2.1, y2.2) .... ))
。。。最终会看起来像

x1   x2   y1.1  y1.2
x1   x2   y2.1  y2.2
到目前为止,我试过的代码大部分都是将其平铺到一行,“x1,x2,y1.1,y1.2,y2.1,y2.2…”等等


任何帮助都将不胜感激,提前感谢

它有点蒸汽驱动,但是:

val l :((BigInt, String), Seq[(BigInt, BigInt)]) = ((1,"two"), List((3,4), (5,6)))
        //> l  : ((BigInt, String), Seq[(BigInt, BigInt)]) = ((1,two),List((3,4), (5,6))
                                                  //| )

for (t <-l._2) yield s"${l._1._1}\t${l._1._2}\t${t._1}\t${t._2}"
        //> res0: Seq[String] = List(1  two 3   4, 1    two 5   6)
val l:((BigInt,String),Seq[(BigInt,BigInt)]=((1,“2”),List((3,4)、(5,6)))
//>l:((BigInt,String),Seq[(BigInt,BigInt)]=((1,2),List((3,4),(5,6))
//| )
for(t res0:Seq[String]=列表(1 2 3 4,1 2 5 6)

似乎有效。不过,我不知道火花是否会干扰这一点。

它有点蒸汽驱动,但是:

val l :((BigInt, String), Seq[(BigInt, BigInt)]) = ((1,"two"), List((3,4), (5,6)))
        //> l  : ((BigInt, String), Seq[(BigInt, BigInt)]) = ((1,two),List((3,4), (5,6))
                                                  //| )

for (t <-l._2) yield s"${l._1._1}\t${l._1._2}\t${t._1}\t${t._2}"
        //> res0: Seq[String] = List(1  two 3   4, 1    two 5   6)
val l:((BigInt,String),Seq[(BigInt,BigInt)]=((1,“2”),List((3,4)、(5,6)))
//>l:((BigInt,String),Seq[(BigInt,BigInt)]=((1,2),List((3,4),(5,6))
//| )
for(t res0:Seq[String]=列表(1 2 3 4,1 2 5 6)

似乎有效。但我不知道火花位是否会干扰此操作。

如果要展平groupByKey()操作的结果,以便将键列和值列展平为一个元组,我建议使用flatMap:

val grouped = sc.parallelize(Seq(((1,"two"), List((3,4), (5,6)))))
val flattened: RDD[(Int, String, Int, Int)] = grouped.flatMap { case (key, groupValues) =>
   groupValues.map { value => (key._1, key._2, value._1, value._2) }
}
// flattened.collect() is Array((1,two,3,4), (1,two,5,6))
从这里,您可以使用其他转换和操作将组合的元组转换为制表符分隔的字符串并保存输出

如果您不关心包含
元组的平坦RDD,那么您可以编写更一般的

 val flattened: RDD[Array[Any]] = grouped.flatMap { case (key, groupValues) =>
   groupValues.map(value => (key.productIterator ++ value.productIterator).toArray)
 }
 // flattened.collect() is Array(Array(1, two, 3, 4), Array(1, two, 5, 6))

另外,请查看
flatMapValues
转换;如果您有一个
RDD[(K,Seq[V]]]]
并且想要
RDD[(K,V)]
,那么如果您想展平groupByKey()的结果,您可以执行
flatMapValues(identity)
操作,以便将键列和值列展平为一个元组,我建议使用flatMap:

val grouped = sc.parallelize(Seq(((1,"two"), List((3,4), (5,6)))))
val flattened: RDD[(Int, String, Int, Int)] = grouped.flatMap { case (key, groupValues) =>
   groupValues.map { value => (key._1, key._2, value._1, value._2) }
}
// flattened.collect() is Array((1,two,3,4), (1,two,5,6))
从这里,您可以使用其他转换和操作将组合的元组转换为制表符分隔的字符串并保存输出

如果您不关心包含
元组的平坦RDD,那么您可以编写更一般的

 val flattened: RDD[Array[Any]] = grouped.flatMap { case (key, groupValues) =>
   groupValues.map(value => (key.productIterator ++ value.productIterator).toArray)
 }
 // flattened.collect() is Array(Array(1, two, 3, 4), Array(1, two, 5, 6))
另外,请查看
flatMapValues
转换;如果您有一个
RDD[(K,Seq[V]])
并且想要
RDD[(K,V)]
,那么您可以执行
flatMapValues(identity)