我的数据框的格式为:
Abc | apple
Abc | mango
xyz | grapes
xyz | peach
我想将此数据帧转换为(键,值列表)的scala映射,例如:(Abc->(苹果,芒果),(xyz->(葡萄,桃子))。
我的代码:
concatenatedLogs.collect.map( r => {
val key = r(0).toString
val value = r(1).toString
var currList = testMap.getOrElse(key,List[String]())
currList = value ::currList
testMap+=(key -> currList)
}
)
它给了我Java堆空间不足内存错误。有没有更有效,更简便的方法来做到这一点?
答案 0 :(得分:2)
Spark是一个分布式处理框架,在您处理大量数据时。 Spark在集群上处理它们,当您调用collect函数时,所有在不同内核/机器上读取的数据都会被带回驱动程序。执行此操作时,需要确保驱动程序上有足够的内存。
您所做的工作效率极低,因为您正在将整个数据帧收集到驱动程序,然后对其进行转换。使用spark,您可以使用以下代码执行类似的操作:
val someDF = Seq(
("Abc", "apple"),
("Abc", "mango"),
("xyz", "grapes"),
("xyz", "peach")
).toDF(
"group", "fruit")
val s = someDF.groupBy(col("group")).
agg(collect_list("fruit").as("fruits")).as[(String, List[String])].collect.toMap
此输出
Map(Abc -> List(apple, mango), xyz -> List(grapes, peach))