首页 > 解决方案 > 如何有效地将数据框对象解析为键值对映射

问题描述

我正在使用带有列basketID和的数据框itemID。有没有办法有效地解析数据集并生成一个映射,其中键basketID和值是itemID每个篮子中包含的所有内容的集合?

我当前的实现在数据帧上使用了一个 for 循环,它的可扩展性不是很好。是否有可能更有效地做到这一点?任何帮助将不胜感激谢谢!

样本数据的屏幕截图

目标是获得basket = Map("b1" -> Set("i1", "i2", "i3"), "b2" -> Set("i2", "i4"), "b3" -> Set("i3", "i5"), "b4" -> Set("i6"))。这是我使用 for 循环的实现

// create empty container
val basket = scala.collection.mutable.Map[String, Set[String]]()
// loop over all numerical indexes for baskets (b<i>)
for (i <- 1 to 4) {
  basket("b" + i.toString) = Set();
}
// loop over every row in df and store the items to the set
df.collect().foreach(row => 
  basket(row(0).toString) += row(1).toString
)

标签: apache-sparkapache-spark-sql

解决方案


您可以简单地进行aggregateByKey操作,然后 collectItAsMap 将直接为您提供所需的结果。它比简单的 groupBy 效率更高。

import scala.collection.mutable
case class Items(basketID: String,itemID: String)
 
 import spark.implicits._
 val result = output.as[Items].rdd.map(x => (x.basketID,x.itemID))
.aggregateByKey[mutable.Buffer[String]](new mutable.ArrayBuffer[String]())
 ((l: mutable.Buffer[String], p: String) => l += p , 
 (l1: mutable.Buffer[String], l2: mutable.Buffer[String]) => (l1 ++ l2).distinct)
.collectAsMap();

您可以在此处查看其他聚合 API,例如 reduceBy 和 groupBy 。另请检查aggregateByKey vs groupByKey vs ReduceByKey差异。


推荐阅读