Python如何高效追加子列表并快速过滤停用词、常用名?
性能优化方案
你当前代码的性能瓶颈来自两个核心原因:
- 列表的
in查询时间复杂度为O(n),如果common_name_lst词汇量很大,每次过滤都要遍历整个列表,耗时会指数级上升 - 存在多处冗余操作:循环内反复实例化分词器、对同一个分词结果多次遍历做过滤、重复转换大小写
核心优化手段
- 将过滤词容器改为集合:提前把
stop_words、common_name_lst转为set类型,set的成员查询时间复杂度为O(1),大词汇量下性能提升可达几十上百倍 - 合并过滤逻辑:把三次列表推导合并为一次,只遍历分词结果一次就完成所有过滤判断,减少遍历开销
- 减少重复运算:分词器在循环外实例化,单词小写转换只做一次,提前把
common_name_lst里的元素统一转小写,避免每次判断时重复转换 - 优先使用向量化操作:原始数据是pandas DataFrame,用
apply代替手动写for循环,底层用C实现的遍历比Python原生for循环快很多
优化后代码
from nltk.tokenize import RegexpTokenizer # 提前处理过滤词集合,统一转小写后合并为一个set,一次查询即可完成两类词过滤 stop_words_set = set(w.lower() for w in stop_words) common_name_set = set(w.lower() for w in common_name_lst) filter_set = stop_words_set.union(common_name_set) # 分词器仅在循环外初始化一次,避免重复创建对象的开销 tokenizer = RegexpTokenizer(r'\w+') def text_processor(text): tokens = tokenizer.tokenize(text) filtered_res = [] for w in tokens: w_lower = w.lower() # 所有过滤条件一次性判断,仅遍历一次分词结果 if w_lower not in filter_set and w.isalpha(): filtered_res.append(w_lower) return filtered_res # 用pandas向量化apply处理全量数据,直接转列表无需手动append wiki_train_lst = wiki_train_df['original_text'].apply(text_processor).tolist()
如果41.6万条数据处理还有性能余量需求,可以引入多进程分块处理DataFrame,进一步压缩耗时。
内容的提问来源于stack exchange,提问作者RRR
相关产品推荐
相关产品推荐

