使用Select Expr与Stack对PySpark DataFrame逆透视未得预期结果
解决PySpark DataFrame逆透视时CPI列与Year列值重复的问题
问题根源在于数字开头的列名未用反引号包裹。Spark中,直接引用以数字开头的列名(比如2018)会被解析成字符串字面量,而非列引用,所以你的stack函数里传入的其实是重复的字符串常量,导致CPI列和Year列值完全一致。
修正后的代码
把数字开头的列名用反引号(`)包裹,让Spark识别为列:
from pyspark.sql import functions as F # 用反引号包裹数字列名 unpivotExpr = "stack(3, '2018', `2018`, '2019', `2019`, '2020', `2020`) as (Year, CPI)" unPivotDF = df.select("Country", F.expr(unpivotExpr)) unPivotDF.show()
正确执行结果
+-------+----+---+ |Country|Year|CPI| +-------+----+---+ | Spain|2018|101| | Spain|2019|201| | Spain|2020|301| | Taiwan|2018|102| | Taiwan|2019|202| | Taiwan|2020|302| | Italy|2018|103| | Italy|2019|203| | Italy|2020|303| | China|2018|104| | China|2019|204| | China|2020|304| +-------+----+---+
更灵活的动态写法
如果后续会新增年份列,不想手动修改表达式,可以动态生成逆透视语句:
from pyspark.sql import functions as F # 自动筛选出年份列(数字开头的列) year_cols = [col for col in df.columns if col.isdigit()] # 动态拼接stack参数 stack_args = ", ".join([f"'{y}', `{y}`" for y in year_cols]) unpivotExpr = f"stack({len(year_cols)}, {stack_args}) as (Year, CPI)" unPivotDF = df.select("Country", F.expr(unpivotExpr)) unPivotDF.show()
内容的提问来源于stack exchange,提问作者Mohammad
相关产品推荐
相关产品推荐

