You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何高效实现DataFrame字符串列与子字符串列表的匹配?

如何高效实现DataFrame字符串列与子字符串列表的匹配?

嘿,我完全懂你遇到的困扰——用拼接正则的str.contains虽然能跑通,但数据量大时速度拉胯,isin和filter又没法满足多子串匹配的需求。下面给你几个实用且高效的解决方案:

1. 优化正则版str.contains(最推荐)

你的原始思路其实没毛病,只是可以更简洁地生成正则模式,加上预编译正则还能进一步提效。把你的子字符串列表直接转成正则表达式,利用pandas底层优化的矢量化操作来处理,比Python层面的循环快得多:

import pandas as pd
import re
import time

t0 = time.time()

df = pd.DataFrame({
    'FullName': ['C:/historical Dog analysis/Digger.doc', 'C:/historical Dog analysis/Roscoe.doc', 'C:/2024/Budgie requests/pipsqueak.csv', 'C:/text4.doc', 'C:/text5.doc'],
})

# 定义你的子字符串列表
substrings = ["/historical Dog analysis/", "/Budgie requests/", "Dog analysis/best practices"]

# 生成正则模式:如果子串含正则特殊字符,用re.escape转义避免出错
pattern = '|'.join(re.escape(sub) for sub in substrings)
# 预编译正则,减少重复解析的开销
compiled_pattern = re.compile(pattern, flags=re.IGNORECASE)

# 直接添加匹配结果列
df["_Outreach/Website design"] = df['FullName'].str.contains(compiled_pattern)

t1 = time.time()
print(t1-t0)
print(df)

2. 纯文本子串的矢量化any匹配

如果你的子串都是普通文本(不需要正则规则),可以用apply结合any来实现,虽然性能略逊于正则版,但代码更直观:

substrings = ["/historical Dog analysis/", "/Budgie requests/", "Dog analysis/best practices"]

# 检查每行字符串是否包含任意子串
df["_Outreach/Website design"] = df['FullName'].apply(lambda x: any(sub in x for sub in substrings))

3. numpy广播极致提效

如果处理超大规模数据,试试numpy的广播机制,它底层用C实现,能彻底避开Python循环的性能瓶颈:

import pandas as pd
import numpy as np
import time

t0 = time.time()

df = pd.DataFrame({
    'FullName': ['C:/historical Dog analysis/Digger.doc', 'C:/historical Dog analysis/Roscoe.doc', 'C:/2024/Budgie requests/pipsqueak.csv', 'C:/text4.doc', 'C:/text5.doc'],
})

substrings = np.array(["/historical Dog analysis/", "/Budgie requests/", "Dog analysis/best practices"])
full_names = df['FullName'].to_numpy()

# 广播匹配,检查每个字符串是否包含任意子串
matches = np.any(np.char.find(full_names[:, None], substrings) != -1, axis=1)
df["_Outreach/Website design"] = matches

t1 = time.time()
print(t1-t0)
print(df)

为啥你的其他方法行不通?

  • isin:它只能做完全字符串匹配,不支持子串包含逻辑,所以没法满足你的需求。
  • filter:本质是Python层面的遍历,不仅每次只能查一个子串,还要手动处理结果对齐,效率和便捷性都远不如矢量化方法。

总结下来,优先选优化后的正则版str.contains,兼顾简洁性和性能;数据量特别大时,numpy广播是更好的选择。

备注:内容来源于stack exchange,提问作者oymonk

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.14 10:58:03