如何用Polars表达式重写map_elements字符串处理函数?
用Polars原生表达式实现需求
你可以通过以下几种Polars原生表达式方法实现相同功能,这些方法都是矢量化操作,性能远优于map_elements:
方法1:分割后选择元素再拼接
先通过str.split将字符串按-分割为列表,选择第0和第2个元素后用str.join拼接,这种方法只需要一次分割操作,效率较高:
import polars as pl data = {"name": ['a', 'b'], "value": ['1-a-2-#', '2-b-3-*']} df = pl.DataFrame(data) df_result = df.with_columns( pl.col('value') .str.split('-') .list.select([0, 2]) # 选择分割后的第0和第2个元素 .str.join('-') # 用'-'拼接选中的元素 .alias('value_new') ) print(df_result)
输出:
shape: (2, 3) ┌──────┬─────────┬───────────┐ │ name ┆ value ┆ value_new │ │ --- ┆ --- ┆ --- │ │ str ┆ str ┆ str │ ╞══════╪═════════╪═══════════╡ │ a ┆ 1-a-2-# ┆ 1-2 │ │ b ┆ 2-b-3-* ┆ 2-3 │ └──────┴─────────┴───────────┘
方法2:分割后直接索引拼接
如果需要更直观的写法,也可以分割后分别取对应索引的元素再拼接:
df_result = df.with_columns( (pl.col('value').str.split('-').list.get(0) + '-' + pl.col('value').str.split('-').list.get(2)) .alias('value_new') )
这种方法会执行两次分割操作,性能略逊于方法1,但逻辑简单易懂。
方法3:正则表达式提取
如果你的value列格式固定(数字-字符-数字-符号),可以用正则表达式直接提取目标数字部分,精准匹配需求:
df_result = df.with_columns( (pl.col('value').str.extract(r'^(\d+)', 1) + '-' + pl.col('value').str.extract(r'-(\d+)-', 1)) .alias('value_new') )
这里^(\d+)匹配开头的数字,-(\d+)-匹配中间被-包裹的数字,通过str.extract提取分组内容后拼接。
以上所有方法都属于Polars原生表达式API,会利用Polars的矢量化引擎批量处理数据,相比map_elements的逐元素Python循环,性能提升显著,尤其在处理大数据集时差距会更明显。
内容的提问来源于stack exchange,提问作者oat
相关产品推荐
相关产品推荐

