
本文介绍使用 Polars 的 unpivot() 方法,将按月聚合的均值与中位数宽表快速转换为适合绘图的长格式数据,替代已弃用的 melt(),代码简洁、语义清晰、无需显式指定变量列。
本文介绍使用 polars 的 `unpivot()` 方法,将按月聚合的均值与中位数宽表快速转换为适合绘图的长格式数据,替代已弃用的 `melt()`,代码简洁、语义清晰、无需显式指定变量列。
在数据可视化前,常需将聚合后的宽格式(wide format)数据——例如按月份分组后计算出的多个统计量(如均值 avg、中位数 med)——转换为长格式(long format),以便按类别(如 type)区分并统一绘制。Polars 提供了专为此类操作设计的 .unpivot() 方法,它是旧版 .melt() 的现代替代方案,更直观、更健壮,且当指定 index 参数时,自动推断其余列为待展开的变量列,无需手动列出。
以下是一个完整、可运行的示例:
import polars as pl
# 模拟聚合后的宽表数据(如 group_by + agg 得到)
df = pl.DataFrame({
'month': ['M202412', 'M202501', 'M202502'],
'avg': [0.037824, 0.036160, 0.038919],
'med': [0.013810, 0.013028, 0.014843],
})
# ✅ 最简方式:使用 unpivot 转为长格式
df_long = df.unpivot(
index="month", # 保留为标识列(不展开)
variable_name="type", # 新列名,存储原列名(如 "avg", "med")
value_name="value" # 新列名,存储对应数值(默认为 "value",可省略)
)
print(df_long)
输出结果为标准长格式 DataFrame,结构清晰,可直接用于主流可视化库(如 Plotly Express、Altair 或 Polars 内置 .plot()):
shape: (6, 3) ┌─────────┬──────┬──────────┐ │ month ┆ type ┆ value │ │ --- ┆ --- ┆ --- │ │ str ┆ str ┆ f64 │ ╞═════════╪══════╪══════════╡ │ M202412 ┆ avg ┆ 0.037824 │ │ M202501 ┆ avg ┆ 0.03616 │ │ M2202502 ┆ avg ┆ 0.038919 │ │ M202412 ┆ med ┆ 0.01381 │ │ M202501 ┆ med ┆ 0.013028 │ │ M202502 ┆ med ┆ 0.014843 │ └─────────┴──────┴──────────┘
注意事项与最佳实践:
- ❌ 避免使用已弃用的
.melt();Polars 官方文档明确推荐unpivot()。 - ✅ 若宽表中存在多个非索引列(如
min,max,std),unpivot(index="month")会自动将其全部展开,无需额外参数。 - ? 如需重命名变量列或值列,可通过
variable_name和value_name显式指定(如variable_name="stat")。 - ? 后续可视化示例(使用 Altair):
import altair as alt chart = alt.Chart(df_long).mark_line().encode( x='month:N', y='value:Q', color='type:N', tooltip=['month', 'type', 'value'] ).properties(width=400, height=350, title="Monthly Avg vs Median") chart.display()
综上,df.unpivot(index="...") 是 Polars 中实现“聚合→可视化就绪”数据形态转换最简洁、最符合惯用法的方式,兼顾可读性、健壮性与性能。










