我是Scala / Spark的新手。我想将List的值转换为仅使用RDD的单独行(无数据帧)。感谢任何人可以帮助我。
输入:
List( ("A",List(10643, 10692)), ("B",List(10308)),("C",List(1000,2000)) )
预期输出:
A 10643
A 10692
B 10308
C 1000
C 2000
我可以单独做,但不能一起做。
这就是我试过的
val Input = sc.makeRDD(List( ("A",List(10643, 10692)), ("B",List(10308)),("C",List(1000,2000)) ))
Input.map(value=>value._1).collect().foreach(println)<
A
B
C
Input.map(value=>value._2).flatMap(x=>x).collect().foreach(println)<br>
10643
10692
10308
1000
2000
答案 0 :(得分:2)
使用函数explode
为给定数组或映射列中的每个元素创建一个新行。
import org.apache.spark.sql.functions._
val data = List( ("A",List(10643, 10692)), ("B",List(10308)),("C",List(1000,2000)) )
val rdd = sc.parallelize(data)
val df = rdd.toDF("name", "list")
val exploded = df.withColumn("value", explode($"list")).drop("list")
exploded.show
如果真的更喜欢使用RDD
val flatted = rdd.flatMap(r => r._2.map((r._1, _)))
答案 1 :(得分:2)
这是一个与Spark无关的解决方案:
val list = List(("A", List(10643, 10692)), ("B", List(10308)), ("C", List(1000, 2000)))
val result = list.flatMap {
case (key, value) => value.map(v => (key, v))
}
result.foreach(println)
// (A,10643)
// (A,10692)
// (B,10308)
// (C,1000)
// (C,2000)
答案 2 :(得分:0)
两种解决方案(第二种解决方案更具可扩展性):
处理驱动程序然后转换为RDD
val in = List( ("A",List(10643, 10692)), ("B",List(10308)),("C",List(1000,2000)) )
val out = sc.parallelize(in.flatMap{case (k, l) => l.map(v => (k,v))})
out.take(10).foreach(println)
转换为RDD然后处理执行程序
val in = List( ("A",List(10643, 10692)), ("B",List(10308)),("C",List(1000,2000)) )
val inRDD = sc.parallelize(in)
val out = inRDD.flatMap{case (k, l) => l.map(v => (k,v))}
答案 3 :(得分:0)
使用PairRDD函数
import scala.collection.mutable._
val df = List( ("A",List(10643, 10692)), ("B",List(10308)),("C",List(1000,2000)) ).toDF("name","list")
val rdd1 = df.rdd.map( x=> (x(0), x(1)))
val pair = new PairRDDFunctions(rdd1)
pair.flatMapValues(_.asInstanceOf[mutable.WrappedArray[Int]]).foreach(println)
结果:
(A,10643)
(B,10308)
(A,10692)
(C,1000)
(C,2000)