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

Databricks中PySpark DataFrame奇数列逆透视错误,求正确方法

问题解答

stack方法是否仅适用于偶数个列?

不是。stack函数的第一个参数指定的是要逆透视的列的数量(即展开后生成的行数),后续每两个参数对应一组(列名标签、列值引用),只要总参数数量满足 1 + 2*N(N为待逆透视的列数)即可,和列数的奇偶性无关。

你的代码错误原因

你代码中的列名(如2015-04-01)包含-字符,直接写2015-04-01会被Spark解析为数学减法运算(2015-4-1),而非列名引用,这才导致错误结果。

正确的逆透视实现方式

方式1:修正原代码的列名引用

将所有列名用反引号(`)包裹,确保Spark正确识别为列名:

from pyspark.sql.functions import expr
group = Inv_df.groupBy('Project', 'Project Description')

# 修正列名引用,用反引号包裹带特殊字符的列名
unpivotExpr = "stack(69, '2015-04-01', `2015-04-01`, '2015-05-01', `2015-05-01`, '2015-06-01', `2015-06-01`, '2015-07-01', `2015-07-01`, '2015-08-01', `2015-08-01`, '2015-09-01', `2015-09-01`, '2015-10-01', `2015-10-01`, '2015-11-01', `2015-11-01`, '2015-12-01', `2015-12-01`, '2016-01-01', `2016-01-01`, '2016-02-01', `2016-02-01`, '2016-03-01', `2016-03-01`, '2016-04-01', `2016-04-01`, '2016-05-01', `2016-05-01`, '2016-06-01', `2016-06-01`, '2016-07-01', `2016-07-01`, '2016-08-01', `2016-08-01`, '2016-09-01', `2016-09-01`, '2016-10-01', `2016-10-01`, '2016-11-01', `2016-11-01`, '2016-12-01', `2016-12-01`, '2017-01-01', `2017-01-01`, '2017-02-01', `2017-02-01`, '2017-03-01', `2017-03-01`, '2017-04-01', `2017-04-01`, '2017-05-01', `2017-05-01`, '2017-06-01', `2017-06-01`, '2017-07-01', `2017-07-01`, '2017-08-01', `2017-08-01`, '2017-09-01', `2017-09-01`, '2017-10-01', `2017-10-01`, '2017-11-01', `2017-11-01`, '2017-12-01', `2017-12-01`, '2018-01-01', `2018-01-01`, '2018-02-01', `2018-02-01`, '2018-03-01', `2018-03-01`, '2018-04-01', `2018-04-01`, '2018-05-01', `2018-05-01`, '2018-06-01', `2018-06-01`, '2018-07-01', `2018-07-01`, '2018-08-01', `2018-08-01`, '2018-09-01', `2018-09-01`, '2018-10-01', `2018-10-01`, '2018-11-01', `2018-11-01`, '2018-12-01', `2018-12-01`, '2019-01-01', `2019-01-01`, '2019-02-01', `2019-02-01`, '2019-03-01', `2019-03-01`, '2019-04-01', `2019-04-01`, '2019-05-01', `2019-05-01`, '2019-06-01', `2019-06-01`, '2019-07-01', `2019-07-01`, '2019-08-01', `2019-08-01`, '2019-09-01', `2019-09-01`, '2019-10-01', `2019-10-01`, '2019-11-01', `2019-11-01`, '2019-12-01', `2019-12-01`, '2020-01-01', `2020-01-01`, '2020-02-01', `2020-02-01`, '2020-03-01', `2020-03-01`, '2020-04-01', `2020-04-01`, '2020-05-01', `2020-05-01`, '2020-06-01', `2020-06-01`, '2020-07-01', `2020-07-01`, '2020-08-01', `2020-08-01`, '2020-09-01', `2020-09-01`, '2020-10-01', `2020-10-01`, '2020-11-01', `2020-11-01`, '2020-12-01', `2020-12-01` ) as (Name, value)"

unPivotDF = group.agg(expr(unpivotExpr))

方式2:动态生成stack表达式(更优雅,避免手动重复)

手动写69组参数容易出错,可通过代码自动生成表达式:

from pyspark.sql.functions import expr

# 定义分组列
group_cols = ['Project', 'Project Description']
# 获取所有待逆透视的列(排除分组列)
unpivot_cols = [col for col in Inv_df.columns if col not in group_cols]

# 生成stack的参数部分:每列对应('列名', `列名`)
stack_params = ", ".join([f"'{col}', `{col}`" for col in unpivot_cols])
# 拼接完整的stack表达式
unpivotExpr = f"stack({len(unpivot_cols)}, {stack_params}) as (Name, value)"

# 执行逆透视
unPivotDF = Inv_df.groupBy(group_cols).agg(expr(unpivotExpr))

这种方式无需手动编写所有列,适配任意数量的待逆透视列,且自动处理带特殊字符的列名。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.14 20:52:03