将Spark Dataframe转换为Scala Map集合

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了将Spark Dataframe转换为Scala Map集合相关的知识,希望对你有一定的参考价值。

我正在尝试找到将整个Spark数据帧转换为scala Map集合的最佳解决方案。最好说明如下:

从这里开始(在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")
)
答案

我不认为你的问题是有道理的 - 你最外面的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"))
)
另一答案

首先从Dataframe获取模式

val schemaList = dataframe.schema.map(_.name).zipWithIndex//get schema list from 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集合的主要内容,如果未能解决你的问题,请参考以下文章

如何将 scala spark.sql.dataFrame 转换为 Pandas 数据框

在scala中将Spark Dataframe转换为RDD

如何将 Scala Spark Dataframe 转换为 LinkedHashMap[String, String]

使用 Scala 将多列转换为 Spark Dataframe 上的一列地图

使用 Spark Dataframe scala 将多个不同的列转换为 Map 列

如何在 Scala(Spark 2.0)中将带有字符串的 DataFrame 转换为带有 Vectors 的 DataFrame