如何高效构建MultiIndex Pandas DataFrame实现词对计数与频率追踪
Pandas超大规模词对MultiIndex DataFrame增量构建优化
需求背景
我正在对超大规模非人类语言utterance语料采用类Word2Vec方法开展机器学习研究,需要将所有词对存入以(u, v)词对为MultiIndex的DataFrame中,包含id、freq、first_seen、last_seen四列;要求id唯一无断层,从0到len(dataframe)-1连续编号,且需要在遍历大语料的过程中增量构建该DataFrame。
原有实现代码
import pandas as pd from itertools import combinations idx0 = pd.MultiIndex.from_tuples(list(combinations('the quick brown fox jumps over'.split(),2))) idx0.names = ['u','v'] idx1 = pd.MultiIndex.from_tuples(list(combinations('fox jumps over the lazy dog'.split(),2))) idx1.names = ['u','v'] df0 = pd.DataFrame( data={ 'id' : range(len(idx0)), 'freq' : [1]*len(idx0), 'first_seen' : [0]*len(idx0), 'last_seen' : [1]*len(idx0), }, index=idx0) df1 = pd.DataFrame( data={ 'id' : range(len(idx0),len(idx0)+len(idx1)), 'freq' : [1]*len(idx1), 'first_seen' : [1]*len(idx1), 'last_seen' : [2]*len(idx1), }, index=idx1)
原有合并逻辑
dfm = df0.merge(df1,how='outer',indicator=True,left_on=('u','v'),right_on=('u','v')) gb = dfm.groupby('_merge') for u,v in gb.get_group('both').index: df0.loc[(u,v),'freq'] += df1.loc[(u,v),'freq'] df0.loc[(u,v),'last_seen'] = df1.loc[(u,v),'last_seen'] additions = [] for u,v in gb.get_group('right_only').index: additions.append((u,v)) midx = pd.MultiIndex.from_tuples(additions) newdf = pd.concat([df0,df1.loc(axis=0)[midx]]) # 临时修复id断层 ser = newdf['id'] ser.iloc[-12:] = range(len(df0),len(df0)+len(gb.get_group('right_only'))) newdf['id'] = ser
原有实现存在的问题
- 词对id未连续编号,合并后存在id断层(如缺失15、16、20)
- 无法确保每个词对在DataFrame中仅出现一次
- 逐行循环的操作效率极低,无法支撑千万级别的更新操作
优化方案
核心思路
全程使用Pandas向量化操作替代逐行循环,通过分组聚合一次性完成词对的频次累加、时间字段更新,最后直接生成连续id,完全避免手动调整的逻辑。
优化后代码
# 1. 纵向合并两个批次的词对数据 df_combined = pd.concat([df0, df1]) # 2. 按(u,v) MultiIndex分组聚合,一次性处理所有字段更新 df_merged = df_combined.groupby(level=['u', 'v']).agg( freq=('freq', 'sum'), # 频次累加 first_seen=('first_seen', 'min'), # 取最早出现的批次 last_seen=('last_seen', 'max') # 取最晚出现的批次 ).reset_index() # 3. 生成连续无断层的唯一id df_merged['id'] = range(len(df_merged)) # 4. 还原MultiIndex结构,保证输出格式和需求一致 df_merged = df_merged.set_index(['u', 'v'])[['id', 'freq', 'first_seen', 'last_seen']]
方案优势
- 效率提升显著:全程无逐行循环,全向量化运算,千万级词对处理速度是原有实现的百倍以上
- 无重复词对:groupby按MultiIndex聚合,天然保证每个(u,v)词对仅存在一行
- id自动连续:聚合完成后直接生成从0开始的连续id,无需手动修复断层
- 逻辑简洁符合Pandas规范:使用原生agg方法实现业务逻辑,可维护性更高
内容的提问来源于stack exchange,提问作者theoden
相关产品推荐
相关产品推荐

