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

Posted

技术标签:

【中文标题】如何将 Scala Spark Dataframe 转换为 LinkedHashMap[String, String]【英文标题】:How to convert a Scala Spark Dataframe to LinkedHashMap[String, String] 【发布时间】:2018-10-31 22:09:30 【问题描述】:

下面是我的数据框:

val myDF= spark.sql("select company, comp_id from my_db.my_table")
myDF: org.apache.spark.sql.DataFrame = [company: string, comp_id: string]

数据看起来像

+----------+---------+
|  company |comp_id  |
+----------+---------+
|macys     |     101 |
|jcpenny   |     102 |
|kohls     |     103 |
|star bucks|     104 |
|macy's    |     105 |
+----------+---------+

我正在尝试根据上述数据框在 Scala 中创建一个 Map 集合对象(如下所示)。

Map("macys" -> "101", "jcpenny" -> "102" ..., "macy's" -> "105")

问题: 1)数据帧记录的顺序是否与表格下方原始文件中内容的顺序相匹配? 2)如果我对数据框执行collect(),创建的数组的顺序是否与原始文件中内容的顺序匹配? 说明:当我执行df.collect().map(t => t(0) -> t(1)).toMap 时,看起来地图集合对象不保留插入顺序,这也是 scala 地图的默认行为。res01: scala.collection.immutable.Map[Any,Any] = Map(kohls -> 103, jcpenny -> 102 ...) 3) 那么,如何将数据帧转换为 scala 的集合映射对象之一,该对象实际上保留了插入顺序/记录序列。 说明:LinkedHashMap 是确保插入顺序的 scala 映射集合对象类型之一。我正在尝试找到一种将数据框转换为LinkedHashMap 对象的方法。

【问题讨论】:

Dataframes、Map 和 Set 集合都保证对象的顺序。 【参考方案1】:

您可以使用来自 Scaladoc 页面的 LinkedHashMap:

“该类使用哈希表实现可变映射。该类的迭代器和所有遍历方法按照插入的顺序访问元素。”

但 Dataframes 不保证顺序总是相同的。

【讨论】:

【参考方案2】:
import collection.mutable.LinkedHashMap
var myMap = LinkedHashMap[String, String]()

myDF.collect().map(t => myMap += (t(0).toString -> t(1).toString))

当你打印myMap

res01: scala.collection.mutable.LinkedHashMap[String,String] = Map(macys -> 101, ..)

【讨论】:

以上是关于如何将 Scala Spark Dataframe 转换为 LinkedHashMap[String, String]的主要内容,如果未能解决你的问题,请参考以下文章

Spark scala Dataframe:如何将自定义类型应用于现有数据框?

如何使用 JSON 映射文件在 Spark 中使用 Scala 生成新的 DataFrame

Spark将DataFrame数据sftp到指定机器(scala)

Spark-Scala:使用异常处理将固定宽度线解析为 Dataframe Api

将 Spark Dataframe 转换为 Scala Map 集合

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