PySpark:如何自动透视含日期列的struct类型DataFrame,无需指定列名?
解决动态列转日期行+货币列的PySpark方案
不用手动指定列名的核心是动态生成转换逻辑,靠PySpark内置函数和自动获取列名实现,具体步骤如下:
1. 自动获取所有日期列
因为你的DataFrame只有1行,所有列都是日期,直接提取列名即可:
date_cols = df.columns
2. 用stack把列转成行
stack函数能把多列转换成键值对格式的行,这里动态生成stack表达式,不用手动罗列所有日期:
# 生成stack表达式:stack(总列数, '日期1', 日期1列, '日期2', 日期2列, ...) stack_expr = f"stack({len(date_cols)}, {', '.join([f'{repr(col)}, `{col}`' for col in date_cols])}) as (date, currency_rates)" # 执行转换,得到每行对应一个日期和其汇率struct df_long = df.selectExpr(stack_expr)
3. 展开struct类型的汇率数据
把每个日期对应的struct转成键值对(货币代码+汇率),先用map_from_struct将struct转为Map类型,再用explode拆分成行:
from pyspark.sql.functions import map_from_struct, explode, col # 转成Map并拆分行 df_exploded = df_long.withColumn("currency_map", map_from_struct(col("currency_rates"))) \ .select("date", explode(col("currency_map")).alias("currency", "rate"))
4. 透视得到最终结构
最后透视货币代码列,将其转为列,日期作为行,用汇率值填充:
from pyspark.sql.functions import first # 用first聚合是因为每个日期+货币只有一个对应值 df_final = df_exploded.groupBy("date").pivot("currency").agg(first("rate"))
整个流程完全不需要手动指定任何日期列或货币代码,全是动态适配你的数据结构。
内容的提问来源于stack exchange,提问作者Rachel Cunningham
相关产品推荐
相关产品推荐

