
在 polars 中,可使用 pl.col(dtype_selector).dt.year().name.map() 等表达式名称操作方法,为所有匹配指定数据类型的列(如 pl.datetime_dtypes)自动派生新列,并按需统一添加前缀、后缀或自定义命名逻辑,无需硬编码列名,实现真正泛化的列变换。
当处理具有相同语义但多个列名的结构化时间数据(如 col1, col2, event_time, created_at)时,手动为每列调用 .alias() 显得冗余且不可扩展。Polars 提供了强大的 表达式名称映射机制(Expression Name Mapping),使你能在列选择与变换的同时,动态重命名输出列。
核心方案是结合三要素:
- 类型选择器:pl.col(pl.DATETIME_DTYPES) 自动匹配所有 datetime 类型列;
- 时间提取操作:.dt.year()、.dt.month()、.dt.day() 等返回对应标量值;
- 名称变换链:通过 .name.map() 对原始列名进行函数式重命名。
✅ 示例:为所有 datetime 列批量生成 _year 后缀列
import polars as pl
data = {"col1": ['2020/01/01', '2020/02/01'], "col2": ['2020/01/01', '2020/02/01']}
df = pl.DataFrame(data, schema={"col1": pl.String, "col2": pl.String})
# 转换为 datetime
df = df.with_columns(
pl.col("col1").str.to_datetime(),
pl.col("col2").str.to_datetime()
)
# 批量提取年份,并自动重命名为 "{原列名}_year"
df = df.with_columns(
pl.col(pl.DATETIME_DTYPES).dt.year().name.map(lambda name: f"{name}_year")
)
print(df)? 输出结果:
shape: (2, 4) ┌─────────────────────┬─────────────────────┬───────────┬───────────┐ │ col1 ┆ col2 ┆ col1_year ┆ col2_year │ │ --- ┆ --- ┆ --- ┆ --- │ │ datetime[μs] ┆ datetime[μs] ┆ i32 ┆ i32 │ ╞═════════════════════╪═════════════════════╪═══════════╪═══════════╡ │ 2020-01-01 00:00:00 ┆ 2020-01-01 00:00:00 ┆ 2020 ┆ 2020 │ │ 2020-02-01 00:00:00 ┆ 2020-02-01 00:00:00 ┆ 2020 ┆ 2020 │ └─────────────────────┴─────────────────────┴───────────┴───────────┘
? 其他常用命名策略(同样适用于任意 dtype 选择器):
- 添加前缀:.name.prefix("year_") → year_col1, year_col2
- 添加后缀:.name.suffix("_yr") → col1_yr, col2_yr
- 多级变换(如转小写 + 加后缀):.name.map(lambda s: s.lower() + "_year")
⚠️ 注意事项:
- pl.DATETIME_DTYPES 是一个元组,包含 pl.Datetime, pl.Date 等;若需同时处理 Date 列,请确保其已正确解析(str.to_date()),否则 .dt.year() 将报错;
- .name.map() 仅作用于当前表达式输出的列名,不影响源列;若某列未被选中或变换失败,不会静默跳过——建议先用 df.schema 校验目标列类型;
- 若需对不同 datetime 列应用不同提取逻辑(如 col1 取年、col2 取季度),则应改用显式列表推导或 select() + 字典解包,而非通配选择器。
? 总结:name.map() 是 Polars 实现“类型驱动、命名可控、零重复”的列批量工程的关键接口。它将列名视为一等公民参与表达式链,让泛化处理从“可行”变为“简洁、健壮、可读”。










