优化Pandas df.apply性能:快速去除DataFrame列中非英文单词
优化方案:快速清理DataFrame中的非英文单词
原代码的核心性能问题
- 重复构建英文单词集合:每次调用
remove_words都重新生成english_words,7000行就要重复7000次5万词的集合构建,这是最大的耗时来源。 - 大小写不匹配:原文本中的单词未转小写,而
brown.words()已转成小写,导致像Fulton这类单词会被误判为非英文。 - 低效的交集计算:
np.intersect1d适合处理大规模数组,但对单句拆分后的几个单词来说,用集合的直接查找/筛选效率更高。
基础优化版代码(快速解决核心问题)
import pandas as pd from nltk.corpus import brown # 只生成一次英文单词集合,放在函数外!集合的查找效率是O(1),远高于列表 english_words = set(w.lower() for w in brown.words()) df = pd.DataFrame() df['text'] = ['the fulton 5ddef', 'aerderdrdfg country grand', 'jury sdcvwefdf said'] df['length'] = [3,3,3] def remove_non_english(words): split_words = words.split() # 遍历单词,转小写后检查是否在英文集合中,保留原单词的大小写和顺序 return [word for word in split_words if word.lower() in english_words] # 应用函数,效率提升数十倍 df['text_clean'] = df['text'].apply(remove_non_english) print(df.head())
进阶批量优化版(适合超大规模DataFrame)
如果7000行数据仍觉得apply不够快,可以用pandas矢量化操作完全摆脱逐行循环:
import pandas as pd from nltk.corpus import brown english_words = set(w.lower() for w in brown.words()) df = pd.DataFrame() df['text'] = ['the fulton 5ddef', 'aerderdrdfg country grand', 'jury sdcvwefdf said'] df['length'] = [3,3,3] # 批量拆分所有文本 df['text_split'] = df['text'].str.split() # 拆分成单单词行 exploded_df = df.explode('text_split') # 标记是否为英文单词 exploded_df['is_english'] = exploded_df['text_split'].str.lower().isin(english_words) # 按原行聚合,保留英文单词 df['text_clean'] = exploded_df[exploded_df['is_english']].groupby(level=0)['text_split'].agg(list) # 空行填充空列表 df['text_clean'] = df['text_clean'].fillna(list()) print(df.head())
优化效果说明
- 提前生成集合:将5万词的集合构建从7000次缩减到1次,直接砍掉99.9%的重复计算。
- 集合查找:O(1)的查找速度比列表的O(n)快几十倍,尤其在5万词的规模下优势明显。
- 批量处理版本:利用pandas的矢量化操作替代逐行循环,处理7000行数据几乎瞬间完成。
内容的提问来源于stack exchange,提问作者Gogo
相关产品推荐
相关产品推荐

