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

Pandas多表字符串匹配效率优化:替代iterrows循环的高效方案

Pandas多条件匹配的高效优化方案

当Table1(3.5w行)和Table2(5k行)用嵌套iterrows+fnmatch实现匹配时,逐行循环的O(M*N)时间复杂度会导致效率极低。以下是几个针对性的优化方案:

1. 预处理倒排索引(最快实现)

先为Table1构建单词/组合到ID的映射字典,后续直接通过字典查询匹配结果,避免重复遍历Table1。

代码示例

# 构建Column C单词到ID的倒排索引
c_word_to_ids = {}
for idx, row in Table1.iterrows():
    word = row['Column C']
    c_word_to_ids.setdefault(word, []).append(idx)

# 构建Column C+Column D组合到ID的倒排索引
cd_pair_to_ids = {}
for idx, row in Table1.iterrows():
    key = (row['Column C'], row['Column D'])
    cd_pair_to_ids.setdefault(key, []).append(idx)

# 批量生成Table2的目标列
Table2['Column E'] = Table2['Column C'].map(lambda x: c_word_to_ids.get(x, []))
Table2['Column F'] = Table2.apply(
    lambda row: cd_pair_to_ids.get((row['Column C'], row['Column D']), []),
    axis=1
)
  • 核心优势:仅遍历Table1两次,后续查询为O(1)字典查找,5k行Table2的处理耗时几乎可忽略。

2. 向量化字符串匹配(简洁高效)

利用Pandas内置的str.contains向量化方法替代逐行循环,结合布尔索引筛选ID,代码简洁且性能远超iterrows。

代码示例(包含匹配)

# 生成Column E:Table1中包含Table2每行Column C的ID
Table2['Column E'] = Table2['Column C'].apply(
    lambda x: Table1[Table1['Column C'].str.contains(x, case=False, na=False)].index.tolist()
)

# 生成Column F:同时包含Column C和Column D的ID
Table2['Column F'] = Table2.apply(
    lambda row: Table1[
        (Table1['Column C'].str.contains(row['Column C'], case=False, na=False)) &
        (Table1['Column D'].str.contains(row['Column D'], case=False, na=False))
    ].index.tolist(),
    axis=1
)

精确匹配版本(更快)

如果需求是精确匹配而非包含,直接用==替代str.contains:

Table2['Column E'] = Table2['Column C'].apply(
    lambda x: Table1[Table1['Column C'] == x].index.tolist()
)
  • 核心优势:无需手动构建字典,代码易读,性能比iterrows提升10-100倍。

3. NumPy布尔矩阵加速(极致性能)

将字符串匹配转换为NumPy布尔矩阵,利用底层C实现的矩阵运算批量获取匹配ID,适合超大数据集场景。

代码示例

import numpy as np

# 提取目标列的NumPy数组
t1_c = Table1['Column C'].values
t2_c = Table2['Column C'].values
t1_d = Table1['Column D'].values
t2_d = Table2['Column D'].values

# 生成Column E的匹配矩阵(Table2每行 vs Table1所有行)
match_c = np.char.find(t1_c.reshape(1, -1), t2_c.reshape(-1, 1)) != -1
Table2['Column E'] = [Table1.index[mask].tolist() for mask in match_c]

# 生成Column F的组合匹配矩阵
match_d = np.char.find(t1_d.reshape(1, -1), t2_d.reshape(-1, 1)) != -1
match_cd = match_c & match_d
Table2['Column F'] = [Table1.index[mask].tolist() for mask in match_cd]
  • 核心优势:NumPy的底层运算比Pandas更高效,适合数据量突破10w级的场景。

4. Dask分布式处理(超大数据量)

如果数据量超过内存限制,用Dask DataFrame替代Pandas,自动拆分数据到多核心/集群并行处理,解决内存不足问题。

代码示例

import dask.dataframe as dd

# 读取数据为Dask DataFrame(支持本地文件/云存储)
dask_t1 = dd.read_csv('table1.csv')
dask_t2 = dd.read_csv('table2.csv')

# 定义匹配函数
def get_matching_ids_c(c_val):
    return dask_t1[dask_t1['Column C'].str.contains(c_val)].index.compute().tolist()

def get_matching_ids_cd(row):
    return dask_t1[
        (dask_t1['Column C'].str.contains(row['Column C'])) &
        (dask_t1['Column D'].str.contains(row['Column D']))
    ].index.compute().tolist()

# 应用函数并计算结果
dask_t2['Column E'] = dask_t2['Column C'].apply(get_matching_ids_c, meta=object)
dask_t2['Column F'] = dask_t2.apply(get_matching_ids_cd, axis=1, meta=object)
result_df = dask_t2.compute()
  • 核心优势:自动处理数据分片与并行计算,支持TB级数据处理。

内容的提问来源于stack exchange,提问作者petchde

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.22 09:03:26