
本文介绍如何在 Polars 中以向量化、可扩展的方式,高效判断一列字符串(B)是否被另一列字符串(A)所包含,避免使用性能差的 map_elements,推荐使用原生的 str.contains() 表达式。
本文介绍如何在 polars 中以向量化、可扩展的方式,高效判断一列字符串(b)是否被另一列字符串(a)所包含,避免使用性能差的 `map_elements`,推荐使用原生的 `str.contains()` 表达式。
在 Polars 中处理字符串包含关系时,初学者常误用 map_elements 配合 Python 原生 in 操作符(如 row["B"] in row["A"]),这种方式虽逻辑直观,但本质是逐行 Python 回调,无法利用 Polars 底层的 Rust 向量化引擎,严重损害性能与可扩展性——尤其在百万级以上数据集上会显著拖慢执行速度,且无法受益于 Polars 的查询优化器和并行计算能力。
正确的做法是使用 Polars 原生表达式 pl.col("A").str.contains(pl.col("B"))。该方法将第二列(B)作为动态模式注入到第一列(A)的正则/子串匹配中,全程在 Rust 层完成向量化计算,支持空值安全、自动广播,并天然兼容惰性执行(.lazy())与物理计划优化。
以下为完整示例:
import polars as pl
df = pl.DataFrame({"A": ["foo", "bar", "foo"], "B": ["f", "b", "s"]})
# ✅ 推荐:向量化、可扩展、高性能
result = df.with_columns(
B_in_A = pl.col("A").str.contains(pl.col("B"))
)
print(result)输出:
shape: (3, 3) ┌─────┬─────┬────────┐ │ A ┆ B ┆ B_in_A │ │ --- ┆ --- ┆ --- │ │ str ┆ str ┆ bool │ ╞═════╪═════╪════════╡ │ foo ┆ f ┆ true │ │ bar ┆ b ┆ true │ │ foo ┆ s ┆ false │ └─────┴─────┴────────┘
⚠️ 注意事项:
- str.contains() 默认启用正则匹配;若 B 列含特殊字符(如 ., *, ^),需设置 literal=True 以启用字面量匹配:
pl.col("A").str.contains(pl.col("B"), literal=True) - 两列长度必须一致(或可广播),否则抛出 ComputeError;
- 若 B 为 null,对应结果为 null(符合三值逻辑),如需转为 False,可链式调用 .fill_null(False);
- 该表达式完全兼容 LazyFrame,建议大数据场景优先使用 .lazy().with_columns(...).collect()。
总结:pl.col("A").str.contains(pl.col("B")) 是 Polars 中实现跨列字符串包含判断的标准、高效且可扩展的方案。它摒弃了反模式的 Python 回调,真正发挥 Polars 的向量化优势,应作为首选实践写入团队数据处理规范。










