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
相关产品推荐
相关产品推荐

