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

Spark Scala:从数组列生成DataFrame多列的技术实现问询

解决方案:Spark Scala 从数组列生成多列

这里有一个完整的Spark Scala实现方案,完美匹配你想要的转换效果:

核心思路

先将数组格式的details列展开为多行,拆分出独立的键值对,再通过**透视(pivot)**操作将行转列为目标格式,缺失的字段会自动填充null。

完整代码示例

import org.apache.spark.sql.functions._
import org.apache.spark.sql.types.IntegerType
import spark.implicits._

// 1. 模拟你的输入DataFrame
val inputDF = Seq(
  ("Toyota", Seq(Seq("year", "2000"), Seq("price", "20000"))),
  ("Audi", Seq(Seq("mpg", "22")))
).toDF("Car name", "details")

// 2. 展开details数组,拆分每个键值对为key和value列
val explodedDF = inputDF
  .select($"Car name", explode($"details").alias("kv_pair")) // 将数组拆分为多行,每个键值对单独成行
  .select(
    $"Car name",
    $"kv_pair"(0).alias("attribute"), // 提取属性名(如year/price/mpg)
    $"kv_pair"(1).cast(IntegerType).alias("value") // 提取属性值并转为整数类型,不需要转类型可去掉cast
  )

// 3. 透视转换:将attribute行转为列,聚合取对应的值
val resultDF = explodedDF
  .groupBy($"Car name")
  .pivot("attribute") // 指定要转为列名的字段
  .agg(first($"value")) // 取每个车辆对应属性的第一个值(因为每个属性唯一,用first/max都可以)

// 查看最终结果
resultDF.show()

代码细节解释

  1. explode函数:把details列的数组元素拆分成独立行,让每个键值对单独占据一行;
  2. 键值对拆分:通过索引kv_pair(0)和kv_pair(1)分别提取属性名和属性值,同时把值转为整数类型(如果需要保留字符串格式,直接去掉cast(IntegerType)即可);
  3. pivot操作:将attribute列的不同取值(year/price/mpg)转换为列名,聚合函数确保每个车辆的每个属性只保留唯一值;
  4. 自动补全null:透视后不存在的属性列会自动填充null,完全符合你期望的目标DataFrame格式。

最终输出结果

运行代码后会得到如下结果:

+--------+----+-----+----+
|Car name|year|price| mpg|
+--------+----+-----+----+
|   Toyota|2000|20000|null|
|     Audi|null| null|  22|
+--------+----+-----+----+

内容的提问来源于stack exchange,提问作者sam8686

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.14 08:04:18