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

Spark DataFrame中指定列转置为行的实现方法咨询

解决方案:Spark DataFrame宽表转窄表(行转列)

当然可以实现这种转换!这种把多列金额数据拆分成多行、按类型归类的操作,在Spark里是非常常见的宽表转窄表场景,我们可以用内置的stack函数来轻松完成,不需要复杂的逻辑。

具体实现步骤

首先,先确认你的Spark版本(stack函数在Spark 2.0及以上版本就已经支持了),接下来直接看代码示例:

1. 创建示例DataFrame

先还原你给出的输入数据:

import org.apache.spark.sql.SparkSession

val spark = SparkSession.builder().appName("AmountUnpivot").master("local[*]").getOrCreate()
import spark.implicits._

// 构建输入DF
val inputDf = Seq(
  (1, 10.00, 5.0),
  (2, 20.0, 3.0)
).toDF("id", "fee_amount", "discount_amount")

inputDf.show()

2. 使用stack函数完成转换

核心就是用stack把指定的列“堆叠”成多行,同时指定对应的类型名称:

// 转换逻辑
val outputDf = inputDf.selectExpr(
  "id",
  "stack(2, 'fee', fee_amount, 'discount', discount_amount) as (amount_type, amount_value)"
)

// 查看结果
outputDf.show()

运行后你会得到完全符合预期的输出:

+---+-----------+------------+
| id|amount_type|amount_value|
+---+-----------+------------+
|  1|        fee|        10.0|
|  1|    discount|         5.0|
|  2|        fee|        20.0|
|  2|    discount|         3.0|
+---+-----------+------------+

代码解释

  • stack(n, ...)里的第一个参数n代表你要转置的列组数量(这里是fee_amount和discount_amount两组,所以n=2)
  • 后面的参数是成对出现的:'类型名称', 对应的列名,比如'fee', fee_amount表示把fee_amount的值归类为fee类型
  • 最后用as (amount_type, amount_value)给新生成的两列指定别名,和你期望的结构完全匹配

如果之后需要扩展更多金额类型(比如tax_amount),只需要调整stack的第一个参数和新增配对即可,比如:

val outputDf = inputDf.selectExpr(
  "id",
  "stack(3, 'fee', fee_amount, 'discount', discount_amount, 'tax', tax_amount) as (amount_type, amount_value)"
)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.21 03:45:08