将 Spark Dataframe 转换为 Scala Map 集合
Posted
技术标签:
【中文标题】将 Spark Dataframe 转换为 Scala Map 集合【英文标题】:Converting a Spark Dataframe to a Scala Map collection 【发布时间】:2016-04-27 16:15:17 【问题描述】:我正在尝试找到将整个 Spark 数据帧转换为 scala 地图集合的最佳解决方案。最好如下图所示:
从此开始(在 Spark 示例中):
val df = sqlContext.read.json("examples/src/main/resources/people.json")
df.show
+----+-------+
| age| name|
+----+-------+
|null|Michael|
| 30| Andy|
| 19| Justin|
+----+-------+
到这样表示的 Scala 集合(Map of Maps):
val people = Map(
Map("age" -> null, "name" -> "Michael"),
Map("age" -> 30, "name" -> "Andy"),
Map("age" -> 19, "name" -> "Justin")
)
【问题讨论】:
【参考方案1】:我认为你的问题没有意义——你最外层的Map
,我只看到你试图将值填入其中——你需要在最外面的Map
中有键/值对。话虽这么说:
val peopleArray = df.collect.map(r => Map(df.columns.zip(r.toSeq):_*))
会给你:
Array(
Map("age" -> null, "name" -> "Michael"),
Map("age" -> 30, "name" -> "Andy"),
Map("age" -> 19, "name" -> "Justin")
)
那时你可以这样做:
val people = Map(peopleArray.map(p => (p.getOrElse("name", null), p)):_*)
这会给你:
Map(
("Michael" -> Map("age" -> null, "name" -> "Michael")),
("Andy" -> Map("age" -> 30, "name" -> "Andy")),
("Justin" -> Map("age" -> 19, "name" -> "Justin"))
)
我猜这确实是你想要的。如果您想在任意Long
索引上键入它们,您可以这样做:
val indexedPeople = Map(peopleArray.zipWithIndex.map(r => (r._2, r._1)):_*)
这给了你:
Map(
(0 -> Map("age" -> null, "name" -> "Michael")),
(1 -> Map("age" -> 30, "name" -> "Andy")),
(2 -> Map("age" -> 19, "name" -> "Justin"))
)
【讨论】:
那行得通。我其实是误会了。我只需要一组地图,而第一行正是我所需要的。谢谢【参考方案2】:首先从 Dataframe 中获取架构
val schemaList = dataframe.schema.map(_.name).zipWithIndex//get schema list from dataframe
从dataframe中获取rdd并映射
dataframe.rdd.map(row =>
//here rec._1 is column name and rce._2 index
schemaList.map(rec => (rec._1, row(rec._2))).toMap
).collect.foreach(println)
【讨论】:
以上是关于将 Spark Dataframe 转换为 Scala Map 集合的主要内容,如果未能解决你的问题,请参考以下文章
将包含 BigInt 的 RDD 转换为 Spark Dataframe
将Spark Dataframe转换为Scala Map集合