
使用 Polars 的 unpivot() 方法可一键将宽格式聚合结果(如按月统计的均值、中位数)转换为适合绘图的长格式,只需指定索引列,无需手动列举变量列。
使用 polars 的 `unpivot()` 方法可一键将宽格式聚合结果(如按月统计的均值、中位数)转换为适合绘图的长格式,只需指定索引列,无需手动列举变量列。
在数据分析流程中,完成分组聚合(如按月份计算均值 avg 和中位数 med)后,常需将结果从宽格式(wide format)转为长格式(long format),以便统一绘制多条折线、堆叠柱状图或使用 Altair/Plotly 等支持 color 或 hue 映射的可视化库。
Polars 提供了语义清晰、性能高效的 unpivot() 方法(自 0.20.0 起替代已弃用的 melt()),是实现该转换的最简方案。其核心优势在于:仅需声明索引列(如 'month'),其余数值列会自动被“展开”为变量名与值对,无需显式传入 value_vars 列表,大幅减少冗余代码并提升可维护性。
以下为完整示例:
import polars as pl
# 假设已完成聚合(注意:原问题中误用了 pd.col,应为 pl.col)
df = (
data.group_by("month_code")
.agg(
pl.col("value").mean().alias("avg"),
pl.col("value").median().alias("med")
)
.sort("month_code")
)
# ✅ 最简转换:使用 unpivot,指定 index 列即可
df_long = df.unpivot(
index="month_code", # 作为分组标识列(x 轴依据)
variable_name="type", # 新列名,存储原列名(如 "avg", "med")
value_name="value" # 新列名,存储对应数值(默认为 "value",可省略)
)
# 输出即为绘图就绪的长格式 DataFrame
print(df_long)
输出结构如下:
shape: (6, 3) ┌────────────┬──────┬──────────┐ │ month_code ┆ type ┆ value │ │ --- ┆ --- ┆ --- │ │ str ┆ str ┆ f64 │ ╞════════════╪══════╪══════════╡ │ M202412 ┆ avg ┆ 0.037824 │ │ M202501 ┆ avg ┆ 0.03616 │ │ M202502 ┆ avg ┆ 0.038919 │ │ M202412 ┆ med ┆ 0.01381 │ │ M202501 ┆ med ┆ 0.013028 │ │ M202502 ┆ med ┆ 0.014843 │ └────────────┴──────┴──────────┘
✅ 注意事项:
-
unpivot()是惰性操作,若上游df为 LazyFrame,结果仍为 LazyFrame;如需立即执行,可链式调用.collect()。 - 若原始聚合结果含多余列(如
count),建议提前用.select()明确保留所需列,避免干扰unpivot逻辑。 - 可直接对接可视化库:例如用 Plotly Express 绘图时,
px.line(df_long, x="month_code", y="value", color="type")即可生成双线趋势图。
总之,df.unpivot(index=...) 是 Polars 生态中转换聚合数据为可视化就绪格式的标准、简洁且高效的方式——告别手动拼接与重复循环,让数据整形回归表达本质。










