4.1 filter:按条件筛选行
import polars as pl
df = pl.DataFrame({
"name": ["Alice", "Bob", "Carol", "Dave"],
"age": [30, 25, 35, 28],
"city": ["北京", "上海", "北京", "广州"],
})
# 单条件
df.filter(pl.col("age") > 28)
# 多条件(AND):传多个参数或用 &
df.filter(
pl.col("age") > 26,
pl.col("city") == "北京",
)
# OR 条件
df.filter(
(pl.col("city") == "上海") | (pl.col("age") > 33)
)
多参数 = AND
filter 接受多个表达式参数时,它们之间是逻辑与关系。这比 & 写法更清爽,推荐。要 OR 就得显式用 |。
4.2 sort:排序
# 单列升序
df.sort("age")
# 降序
df.sort("age", descending=True)
# 多键排序:先按 city 升,再按 age 降
df.sort(["city", "age"], descending=[False, True])
# 按表达式排序:如按 name 长度
df.sort(pl.col("name").str.len_chars())
# null 放最后
df.sort("age", nulls_last=True)
4.3 head / tail / limit / sample
df.head(2) # 前 2 行
df.tail(2) # 后 2 行
df.limit(3) # 同 head
df.sample(n=2) # 随机 2 行
df.slice(1, 2) # 从第 1 行起取 2 行
# top_k / bottom_k:不必全排序即可取极值行
df.top_k(2, by="age") # age 最大的 2 行
4.4 unique:去重
# 整行去重
df.unique()
# 按子集去重,保留首次出现
df.unique(subset=["city"], keep="first")
# 某列有多少不同取值
df.select(pl.col("city").n_unique())
# 各取值出现次数
df.select(pl.col("city").value_counts())
4.5 条件表达式 when / then / otherwise
Polars 没有 if-else 用在列上,而是用链式的 when().then().otherwise(),向量化、可嵌套。
- pl.when(condition)
- 开始一个条件分支,参数是一个布尔表达式。
- .then(value)
- 条件为真时取的值,可以是字面量,也可以是另一个表达式(如另一列)。
- .otherwise(value)
- 所有条件都不满足时的默认值。省略则为
null。 - 链式多分支
- 可以
when().then().when().then().otherwise()表达多路分支,类似 SQL 的CASE WHEN。 - 向量化
- 整个条件表达式对整列一次性求值,不像 Python 循环逐行判断,性能高。
- 与 apply 的区别
- 能用 when/then 表达的逻辑,绝不要退回到
map_elements(逐行 Python 回调)——后者慢几十倍。
df = pl.DataFrame({"score": [92, 78, 55, 88]})
df.with_columns(
pl.when(pl.col("score") >= 90).then(pl.lit("A"))
.when(pl.col("score") >= 80).then(pl.lit("B"))
.when(pl.col("score") >= 60).then(pl.lit("C"))
.otherwise(pl.lit("F"))
.alias("grade")
)
# grade: ["A", "C", "F", "B"]
4.6 链式管道风格
Polars 鼓励把多步操作写成一条清晰的链,每步返回新 DataFrame,无副作用。
result = (
df
.filter(pl.col("score") >= 60)
.with_columns(
pl.when(pl.col("score") >= 90)
.then(pl.lit("优秀"))
.otherwise(pl.lit("及格"))
.alias("level")
)
.sort("score", descending=True)
)
无副作用
Polars 操作永远返回新对象,不修改原 DataFrame(没有 pandas 的 inplace=True,也就没有 SettingWithCopyWarning)。这让链式管道天然安全、易读、易并行。
4.7 小结与下一步
filter多参数即 AND,OR 用|;sort支持多键、表达式、null 位置。head/tail/top_k/unique/n_unique覆盖取样与去重。- 条件逻辑用向量化的
when/then/otherwise,别退回逐行 Python。 - Polars 无副作用,适合写清晰的链式管道。
- 下一章进入 分组聚合 groupby 与窗口表达式。