3.1 表达式:Polars 的核心抽象
pandas 里你写 df["a"] + df["b"],是对具体数据的操作。Polars 引入了一层表达式(Expression)——它不是数据,而是"要做什么运算"的蓝图。表达式在 select/with_columns/filter/group_by().agg() 等上下文里被"执行",Polars 可以并行运行多个独立表达式,并在 Lazy 模式下优化它们。
- Expression(表达式)
- 描述"对某些列做什么运算"的对象,惰性、可组合、无副作用。如
pl.col("a") * 2本身不算任何东西,直到放进上下文。 - pl.col()
- 引用一列或多列。
pl.col("a")选一列,pl.col("a", "b")选多列,pl.col(pl.Int64)按类型选,pl.col("*")或pl.all()选全部。 - pl.lit()
- 字面量(literal)表达式,把一个标量常数包装成表达式,用于与列运算,如
pl.col("x") * pl.lit(2)。多数时候可直接写* 2,Polars 自动包装。 - select
- 上下文:产出一个新 DataFrame,只包含表达式指定的列。原有列若没选就丢掉。
- with_columns
- 上下文:在保留原有所有列的基础上,新增或覆盖列。最常用于派生新特征。
- alias
- 给表达式结果重命名。
(pl.col("a") + pl.col("b")).alias("sum"),否则结果列名默认取第一个引用列的名字。 - 表达式扩展(Expression Expansion)
- 一个表达式引用多列时,会自动对每列展开成一组表达式。如
pl.col("a", "b") * 2等价于分别对 a、b 乘 2。
3.2 select:投影出新表
import polars as pl
df = pl.DataFrame({
"a": [1, 2, 3],
"b": [10, 20, 30],
})
# 选列 + 计算 + 重命名
out = df.select(
pl.col("a"),
(pl.col("a") + pl.col("b")).alias("total"),
(pl.col("b") / 10).alias("b_scaled"),
)
# 结果只有 a / total / b_scaled 三列
3.3 with_columns:新增列
# 保留 a、b,再加两列
out = df.with_columns(
(pl.col("a") * 100).alias("a100"),
(pl.col("a") > 1).alias("a_gt_1"),
)
# 结果有 a / b / a100 / a_gt_1 四列
# 覆盖已有列:同名即覆盖
out = df.with_columns(pl.col("a") * 2)
select vs with_columns 记忆法
select = "只要这些列"(做减法/投影);with_columns = "在原表上再添几列"(做加法)。二者接受的表达式语法完全一致。
3.4 算术与比较
df.select(
(pl.col("a") + pl.col("b")), # 加
(pl.col("b") - pl.col("a")), # 减
(pl.col("a") * pl.col("b")), # 乘
(pl.col("b") / pl.col("a")), # 除
(pl.col("b") % 7), # 取模
)
df.select(
(pl.col("a") > 1), # 大于 → Boolean 列
(pl.col("a") == 2), # 等于
(pl.col("a").is_in([1, 3])), # 成员判断
)
3.5 逻辑组合
多个布尔表达式用 &(与)、|(或)、~(非)组合,务必给每个条件加括号。
expr = (pl.col("a") > 1) & (pl.col("b") < 30)
df.filter(expr)
# 也可以链式写法(更清晰)
expr = (pl.col("a") > 1).and_(pl.col("b") < 30)
括号陷阱
Python 里 & 的优先级高于比较运算符,所以 pl.col("a") > 1 & pl.col("b") < 30 会被误解析。永远给每个比较条件套括号:(...) & (...)。
3.6 表达式扩展与选择器
# 对多列一次性操作
df.select(pl.col("a", "b") * 2) # a、b 都乘 2
df.select(pl.all() * 2) # 所有列乘 2
df.select(pl.col(pl.Int64).sum()) # 所有 Int64 列求和
# selectors:更强大的列选择(推荐)
import polars.selectors as cs
df.select(cs.numeric()) # 所有数值列
df.select(cs.starts_with("a")) # 名字以 a 开头的列
3.7 一个综合例子
df = pl.DataFrame({
"qty": [2, 5, 1],
"price": [9.9, 19.9, 99.0],
})
result = df.with_columns(
(pl.col("qty") * pl.col("price")).alias("amount"),
(pl.col("price") > 50).alias("is_expensive"),
).select(
pl.col("amount").round(2),
pl.col("amount").sum().alias("total"), # 聚合与逐行混用
)
3.8 小结与下一步
- 表达式是 Polars 的核心抽象:惰性、可组合、可并行、可优化。
pl.col引用列,pl.lit包字面量,alias重命名。select做投影、with_columns做新增;语法一致。- 布尔组合用
& | ~并加括号;多列用表达式扩展或 selectors。 - 下一章用表达式来 过滤、排序、条件选择。