You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何高效将Scala DataFrame转换为以Code为键的HashMap结构

Scala实现DataFrame按分组字段转嵌套HashMap结构

实现思路

利用Spark原生分布式算子完成分组聚合,避免Driver端单节点处理全量数据,性能最优:

  1. 先将非分组字段封装为结构体,保证分组后同组数据的字段关联关系
  2. 按Code字段分组,用collect_list收集同组所有结构体数据
  3. (仅小数据集适用)将聚合后的数据拉取到Driver端,转换为目标HashMap结构

实现代码

import org.apache.spark.sql.functions._
import scala.collection.mutable.HashMap

// 假设你的原始DataFrame变量名为df
val resultDf = df.groupBy("Code")
  .agg(collect_list(struct("Name", "Age", "ID")).as("records"))

// 拉取到Driver端转HashMap,仅适合结果集不大的场景
val targetMap: HashMap[String, List[Map[String, Any]]] = HashMap(
  resultDf.collect().map(row => {
    val code = row.getAs[String]("Code")
    val records = row.getAs[Seq[org.apache.spark.sql.Row]]("records").map(recordRow => 
      Map(
        "Name" -> recordRow.getAs[String]("Name"),
        "Age" -> recordRow.getAs[Int]("Age"),
        "ID" -> recordRow.getAs[Int]("ID")
      )
    ).toList
    code -> records
  }): _*
)

注意事项

  • 若数据量极大,不要直接调用collect拉取全量数据到Driver,可直接将resultDf写入外部存储(如HDFS、数据库等)
  • 如需类型安全,可提前定义样例类封装用户字段,避免Row的弱类型问题:
    case class User(Name: String, Age: Int, ID: Int)
    // 转换Row为样例类的逻辑替换为:
    val records = row.getAs[Seq[Row]]("records").map(r => User(r.getAs[String]("Name"), r.getAs[Int]("Age"), r.getAs[Int]("ID"))).toList
    

内容的提问来源于stack exchange,提问作者Asad Bin Imtiaz

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.08 20:30:04