优化pandas列表列元素频次统计 降低复杂度与运行耗时
词元频次统计高效实现方案
你原有代码运行慢的核心原因有两点:
- 循环中反复调用
DataFrame.append(),该操作每次执行都会全量复制已有DataFrame,数据量较大时时间开销会呈平方级增长 - 多轮不必要的DataFrame结构转换,额外消耗了大量计算资源
不需要手写逐行循环,pandas提供了内置方法可以用几行代码高效完成需求,以下是两种经过验证的高性能实现:
方案1:纯pandas内置实现(代码最简洁)
使用explode()直接将存储列表的列拆分为单元素行,再调用value_counts()完成频次统计,全程无手写循环:
import pandas as pd def get_dictionary(input: pd.Series) -> pd.DataFrame: freq = input.explode().value_counts().reset_index() freq.columns = ['tokens', 'count'] return freq
该方案在你描述的18万行数据集上运行耗时通常在几百毫秒级别。
方案2:Counter实现(性能最优,适合高频调用场景)
如果需要反复运行该函数追求极致速度,可以搭配Python标准库的collections.Counter,比纯pandas实现速度还要快30%左右:
import pandas as pd from collections import Counter import itertools def get_dictionary(input: pd.Series) -> pd.DataFrame: # 拼接所有词元为单个迭代器,一次性完成计数 all_tokens = itertools.chain.from_iterable(input) token_count = Counter(all_tokens) # 转换为目标结构的DataFrame,可按需选择是否排序 return pd.DataFrame( token_count.items(), columns=['tokens', 'count'] ).sort_values(by='count', ascending=False, ignore_index=True)
注意:不要在循环中反复执行
append、concat这类会生成新DataFrame对象的操作,这类写法是最常见的pandas性能陷阱,数据量越大性能损耗越明显。
内容的提问来源于stack exchange,提问作者Ber Tsacianegu del Tepuy
相关产品推荐
相关产品推荐

