从地图阵列的RDD获取最大的地图

时间:2016-05-26 07:36:30

标签: scala csv apache-spark rdd

我在这样的RDD中有一个地图数组:

Map("id" -> 1, "name" -> "punit")
Map("id" -> 2, "name" -> "naik", "ph_no" -> 123123)

现在我的目标是将这个地图数组写入CSV文件,如下所示:

id,ph_no,name
1,,punit
2,123123,naik

ID 1未提供ph_no,这就是CSV中为空的原因。所以我想遍历这个RDD并找到具有最大大小的Map,这样我就可以通过提取它的键来命名标题中的所有字段。

用scala术语表示:

val x = Array(Map("id" -> 1, "name" -> "punit"),Map("id" -> 2, "name" -> "naik", "ph_no" -> 123123)).maxBy(_.size)

这将正确地给我:

res0: scala.collection.immutable.Map[String,Any] = Map(id -> 2, name -> naik, ph_no -> 123123)

我该怎么做?

2 个答案:

答案 0 :(得分:3)

您可以使用.max(),按地图大小指定排序。

scala> val rdd = sc.parallelize(Array(Map("id" -> 1, "name" -> "punit"),Map("id" -> 2, "name" -> "naik", "ph_no" -> 123123)))
rdd: org.apache.spark.rdd.RDD[scala.collection.immutable.Map[String,Any]] = ParallelCollectionRDD[0] at parallelize at <console>:27

scala> val maxMap = rdd.max()(Ordering.by(_.size))
maxMap: scala.collection.immutable.Map[String,Any] = Map(id -> 2, name -> naik, ph_no -> 123123)

顺便说一下,因为您使用的是CSV文件,所以使用spark-csv可能会感兴趣。

答案 1 :(得分:3)

查找最大大小的Map元素可能不够准确,因为它们可能都没有所有数据(从示例中判断)。 您可以通过在地图中执行所有不同键的并集来获取标题列表。 类似的东西:

val rddOfMaps:RDD[Map[String,Any]] = sc.parallelize(Seq(Map("a"->1, "b"->2, "d"->3),Map("a"->2, "c"->4, "e" -> 1)))
val headers = rddOfMaps.flatMap(entry => entry.keySet).distinct.collect
val csvData = rddOfMaps.map(entry => header.map(column => entry.get(column).getOrElse("")).mkString(","))

// 1,2,,3,
// 2,,4,,1