我正在使用Spark Scala,需要将Map[String, String]
保存到磁盘上,以便其他Spark应用程序可以读取它。
(x,1),(y,2)...
要保存:
sc.parallelize(itemMap.toSeq).coalesce(1).saveAsTextFile(fileName)
我正在合并,因为数据只有450行。
但是要读回去,我无法将其转换回Map[String, String]
val myMap = sc.textFile(fileName).zipWithUniqueId().collect.toMap
数据来自
((x,1),0),((y,2),1)...
可能的解决方案是什么?
谢谢。
答案 0 :(得分:0)
加载文本文件会导致RDD[String]
,因此您将不得不反序列化元组的字符串表示形式。
您可以更改保存操作,以在元组值1和元组值2之间添加定界符,或解析字符串(:v1, :v2)
。
val d = spark.sparkContext.textFile(fileName)
val myMap = d.map(s => {
val parsedVals = s.substring(1, s.length-1).split(",")
(parsedVals(0), parsedVals(1))
}).collect.toMap
或者,您可以更改保存操作以创建定界符(如逗号)并以这种方式解析结构:
itemMap.toSeq.map(kv => kv._1 + "," + kv._2).saveAsTextFile(fileName)
val myMap = spark.sparkContext.textFile("trash3.txt")
.map(_.split(","))
.map(d => (d(0), d(1)))
.collect.toMap
答案 1 :(得分:0)
方法“ collectAsMap”存在于“ PairRDDFunctions”类中,意味着仅适用于具有两个值RDD [(K,V)]的RDD。
如果需要此函数调用,可以使用下面的代码进行组织。数据框用于以csv格式存储,避免了手工解析
Post
输出:
val originalMap = Map("x" -> 1, "y" -> 2)
// write
sparkContext.parallelize(originalMap.toSeq).coalesce(1).toDF("k", "v").write.csv(path)
// read
val restoredDF = spark.read.csv(path)
val restoredMap = restoredDF.rdd.map(r => (r.getString(0), r.getString(1))).collectAsMap()
println("restored map: " + restoredMap)