
使用 Polars 的 unpivot() 方法可一键将宽格式聚合结果(含 month、avg、med 等列)转换为适合绘图的长格式,指定 index="month" 即自动展开其余数值列,无需手动列举变量。
使用 polars 的 `unpivot()` 方法可一键将宽格式聚合结果(含 month、avg、med 等列)转换为适合绘图的长格式,指定 `index="month"` 即自动展开其余数值列,无需手动列举变量。
在数据分析流程中,完成按时间分组的统计聚合(如月度均值、中位数)后,常需将结果转换为「长格式」(long format)以兼容主流可视化库(如 Plotly、Altair 或 Polars 自带的 .plot)。Polars 提供了语义清晰、性能高效的 unpivot() 方法——它是旧版 melt() 的现代替代,专为这类结构化重塑设计。
假设你已通过 Polars 完成如下聚合:
df = (
data.group_by("month_code")
.agg(
pl.col("value").mean().alias("avg"),
pl.col("value").median().alias("med")
)
.sort("month_code")
)
# 注意:此处无需 .collect(),保持 LazyFrame 更高效
得到宽格式 DataFrame:
shape: (3, 3) ┌────────────┬──────────┬──────────┐ │ month_code ┆ avg ┆ med │ │ --- ┆ --- ┆ --- │ │ str ┆ f64 ┆ f64 │ ╞════════════╪══════════╪══════════╡ │ M202412 ┆ 0.037824 ┆ 0.01381 │ │ M202501 ┆ 0.03616 ┆ 0.013028 │ │ M202502 ┆ 0.038919 ┆ 0.014843 │ └────────────┴──────────┴──────────┘
只需一行即可完成重塑:
df_long = df.unpivot(index="month_code", variable_name="type", value_name="value")
✅ index="month_code":声明保留为标识列(即 x 轴维度);
✅ variable_name="type":指定新列名,用于存储原列名(如 "avg"、"med"),对应图例分组;
✅ value_name="value":指定新列名,存放被展开的数值(默认为 "value",可省略)。
输出即为标准长格式,可直接传入可视化接口:
# 示例:使用 Polars 内置绘图(需 polars[plot])
df_long.plot.line(x="month_code", y="value", color="type",
title="Monthly Avg vs Median", width=400, height=350)
# 或导出为 pandas(如需 Altair/matplotlib)
df_pandas = df_long.to_pandas()
⚠️ 注意事项:
-
unpivot()是惰性操作(LazyFrame 支持),避免过早.collect(); - 若原始列名含空格或特殊字符,
unpivot仍能正确处理,但建议命名时保持简洁(如avg,med); - 不要混淆
unpivot()与pivot():前者「列→行」(宽→长),后者「行→列」(长→宽); - 若需对特定列展开(而非除 index 外全部列),可显式传入
on=["avg", "med"]参数。
总结:df.unpivot(index="month", variable_name="type") 是 Polars 中实现聚合结果可视化就绪转换的最简、最健壮方案——语义明确、零冗余代码、完全惰性且向后兼容。










