apache-spark - 如何有效地将数据框对象解析为键值对映射
问题描述
我正在使用带有列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
)
解决方案
您可以简单地进行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差异。
推荐阅读
- typescript - 从 webview 向扩展发送消息
- google-apps-script - 如何将 Google 照片中的一张图片添加到 HTML 模板以发送电子邮件?
- api - Pinterest 开发者 API v3 应用程序仍在等待中
- html - CSS中的中心页脚
- excel - ListBox(用户窗体)VBA中的多列
- pandas - 熊猫根据条件合并和更新,而不重命名列
- django - 将图像提供给 Django 模板
- asp.net - 任何人都知道为什么邮递员从不在我的 sql 表上的字段返回空值?
- python - 从 pandas 数据框中选择特定行
- c - 是否有在 C 中返回条件整数(错误代码)的简写?这有点类似于 Go