
本文介绍在 Polars 中高效删除所有列值均为 0 的行的两种主流方法:使用 remove() 配合 all_horizontal(),或用 filter() 取反逻辑;同时对比说明如何删除含任意零值的行。
本文介绍在 polars 中高效删除所有列值均为 0 的行的两种主流方法:使用 remove() 配合 all_horizontal(),或用 filter() 取反逻辑;同时对比说明如何删除含任意零值的行。
在 Polars 中,虽然没有内置的 drop_all_zeros() 这类专用函数,但借助其强大的布尔表达式组合能力,可以简洁、高效地实现全零行过滤。核心思路是:构造一个布尔掩码,标识出“所有列同时等于 0”的行,再将其移除或排除。
✅ 方法一:使用 remove()(推荐,语义清晰)
remove() 是 Polars 提供的专门用于按条件删除行的方法,语法直观且意图明确:
import polars as pl
df = pl.DataFrame({
"a": [0, 0, 0, 0, 30],
"b": [0, 0, 0, 0, 40],
"c": [0, 0, 0, 0, 50]
})
# 删除所有列值均为 0 的行
result = df.remove(pl.all_horizontal(pl.all() == 0))
print(result)
输出:
shape: (1, 3) ┌─────┬─────┬─────┐ │ a ┆ b ┆ c │ │ --- ┆ --- ┆ --- │ │ i64 ┆ i64 ┆ i64 │ ╞═════╪═════╪═════╡ │ 30 ┆ 40 ┆ 50 │ └─────┴─────┴─────┘
其中:
-
pl.all()表示对 DataFrame 中所有数值列(忽略结构化类型如 List、Struct)生成逐列比较表达式; -
pl.all() == 0生成每列是否为 0 的布尔列; -
pl.all_horizontal(...)将这些布尔列按行做逻辑与(AND),仅当所有列为True时结果才为True; -
remove()直接移除满足该条件的所有行。
✅ 方法二:使用 filter()(等价替代,更通用)
若习惯使用筛选思维,也可用 filter() 对条件取反(~):
result = df.filter(~pl.all_horizontal(pl.all() == 0))
效果完全一致。filter() 更常用于保留数据的场景,而 remove() 在“清理”语义下更具可读性。
⚠️ 注意事项与最佳实践
-
类型安全:
pl.all()默认只作用于数值列(numericdtypes),不会误匹配字符串、布尔或嵌套类型列,无需额外类型过滤。 - 性能优势:上述写法全程在 Polars 查询引擎内执行,避免 Python 层循环,适合百万级数据。
-
扩展用法:
- 若需删除任意一列含 0 的行(即“至少一个零”),将
all_horizontal替换为any_horizontal:df.remove(pl.any_horizontal(pl.all() == 0)) # 删除含任意 0 的行
- 若需自定义列范围(如仅检查
"a"和"c"列),可用pl.col(["a", "c"])替代pl.all()。
- 若需删除任意一列含 0 的行(即“至少一个零”),将
✅ 总结
| 场景 | 推荐写法 |
|---|---|
| 删除全零行(所有列 = 0) | df.remove(pl.all_horizontal(pl.all() == 0)) |
| 删除含零行(任一列 = 0) | df.remove(pl.any_horizontal(pl.all() == 0)) |
| 需兼容旧版本或偏好 filter 风格 | df.filter(~pl.all_horizontal(pl.all() == 0)) |
掌握 pl.all() 与 all_horizontal/any_horizontal 的组合,是写出简洁、高性能 Polars 数据清洗逻辑的关键技巧之一。










