Polars优化方案:基于另一列移除子串,替代apply-lambda方法
Polars优化方案替代apply-lambda移除子串
问题说明
针对Stack Overflow帖子《Remove substring from column based on another column》里的apply-lambda实现方式,有没有Polars的优化方案?另外,给定如下Polars DataFrame,需要根据sub列的值移除origin列里的_<sub>子串,得到指定的预期输出。
原始DataFrame
import polars as pl df = pl.DataFrame( {"origin": ["id1_COUNTRY", "id2_NAME"], "sub": ["COUNTRY", "NAME"]} )
对应的表格展示:
shape: (2, 2) ┌─────────────┬─────────┐ │ origin ┆ sub │ │ --- ┆ --- │ │ str ┆ str │ ╞═════════════╪═════════╡ │ id1_COUNTRY ┆ COUNTRY │ │ id2_NAME ┆ NAME │ └─────────────┴─────────┘
预期输出
shape: (2, 3) ┌─────────────┬─────────┬─────┐ │ origin ┆ sub ┆ out │ │ --- ┆ --- ┆ --- │ │ str ┆ str ┆ str │ ╞═════════════╪═════════╪═════╡ │ id1_COUNTRY ┆ COUNTRY ┆ id1 │ │ id2_NAME ┆ NAME ┆ id2 │ └─────────────┴─────────┴─────┘
优化实现方案
Polars的向量化字符串操作完全可以替代低效的apply-lambda逐行处理,大数据量下性能优势明显,这里提供几种实用方法:
方法1:动态构造子串替换
直接构造要移除的_+sub字符串,用str.replace完成向量化替换:
df = df.with_columns( pl.col("origin").str.replace(pl.concat_str(["_", pl.col("sub")]), "").alias("out") )
方法2:按分隔符分割取前缀
如果origin的格式固定为前缀_子串,直接按_分割后取第一个元素更简洁高效:
df = df.with_columns( pl.col("origin").str.split("_").list.first().alias("out") )
方法3:动态正则匹配(通用场景)
如果需要确保只替换末尾的_<sub>(避免中间内容误匹配),可以用动态生成的正则表达式:
df = df.with_columns( pl.col("origin").str.replace(pl.format(r"_{}$", pl.col("sub")), "").alias("out") )
这里的_{}$正则表示匹配字符串末尾的_加sub列内容。
以上三种方法运行后都能得到预期输出,且都是Polars原生的向量化操作,性能远优于apply-lambda。
内容的提问来源于stack exchange,提问作者yz_jc
相关产品推荐
相关产品推荐

