优化子字符串搜索与新DataFrame创建的代码方案咨询
优化pandas子字符串匹配的高效方案
核心优化思路
原代码的双重循环+iterrows逐行迭代在大数据集下效率极低,我们可以利用pandas的矢量化字符串操作替代循环——这类操作基于C实现,性能远高于Python级别的循环。
方案一:正则匹配+矢量化筛选(最优推荐)
将unit_list转换为正则表达式的"或"模式,直接用str.contains批量匹配,一步完成筛选:
import re import pandas as pd # 转义unit中的正则特殊字符(如.、*等),避免匹配出错 escaped_units = [re.escape(unit) for unit in unit_list] # 构建正则匹配模式:匹配任意一个unit子串 match_pattern = '|'.join(escaped_units) # 筛选Column2中包含任意unit的行,保留原索引和Column2 save_df = df_tp[ df_tp['Column2'].astype(str).str.contains(match_pattern, na=False) ].reset_index() # 调整列名和顺序,符合需求 save_df = save_df.rename(columns={'index': 'Column1'})[['Column1', 'Column2']]
关键细节:
astype(str):确保非字符串类型(如数字、空值)能被正确转为字符串进行匹配na=False:直接排除Column2为空值的行,避免匹配报错- 正则转义:如果
unit_list里包含.、*这类正则特殊字符,re.escape会自动转义,保证匹配的是字面量
方案二:按需匹配首个符合的unit(兼容原代码逻辑)
如果需要和原代码一样,只要匹配到unit_list中的第一个符合项就停止检查,可以用apply结合生成器,但性能略低于方案一:
def match_first_unit(val): val_str = str(val) return next((True for unit in unit_list if unit in val_str), False) # 筛选符合条件的行 save_df = df_tp[df_tp['Column2'].apply(match_first_unit)].reset_index() save_df = save_df.rename(columns={'index': 'Column1'})[['Column1', 'Column2']]
原代码的性能问题点
iterrows:逐行迭代DataFrame本质是把每行转成Series,比矢量化操作慢10~100倍save_df.loc[index]:动态添加行会频繁触发DataFrame内存重分配,大数据集下会显著拖慢速度
内容的提问来源于stack exchange,提问作者khankhattak
相关产品推荐
相关产品推荐

