Python Pandas:获取两DataFrame公共行对应的df2行索引
高效找出df2中与df1存在公共行的行索引
针对你处理百万级DataFrame的需求,你的原始方法虽然能实现功能,但逐行拼接字符串的apply操作在大数据量下效率极低。这里提供两种基于Pandas矢量化优化的高效方案,能大幅提升处理速度:
方案1:利用merge直接匹配并保留索引
这种方法通过Pandas的merge函数(底层优化的矢量化操作)直接按指定列匹配公共行,同时保留df2的索引,是处理大数据最稳妥的方式之一:
import pandas as pd # 初始化数据(注意统一列类型,避免类型不匹配导致匹配失败) df1 = pd.DataFrame({'col1':['cx','cx','cx2'], 'col2':[1,4,12]}) df2 = pd.DataFrame({'col1':['cx','cx','cx','cx','cx2','cx2'], 'col2':[1,3,5,10,12,12]}) df1['col2'] = df1['col2'].astype(str) df2['col2'] = df2['col2'].astype(str) # 内连接匹配公共行,left_index=True保留df2的索引 merged_df = df2.merge(df1, on=['col1', 'col2'], how='inner', left_index=True) # 提取并去重df2的索引(如果df2有重复匹配行,去重可避免重复索引) target_indexes = merged_df.index.unique().tolist() print(target_indexes) # 输出: [0, 4, 5]
方案2:使用MultiIndex的isin方法
这种方法通过将匹配列转为MultiIndex,利用isin的底层优化实现快速筛选,代码更简洁:
import pandas as pd df1 = pd.DataFrame({'col1':['cx','cx','cx2'], 'col2':[1,4,12]}) df2 = pd.DataFrame({'col1':['cx','cx','cx','cx','cx2','cx2'], 'col2':[1,3,5,10,12,12]}) # 统一列类型 df1['col2'] = df1['col2'].astype(str) df2['col2'] = df2['col2'].astype(str) # 将匹配列转为MultiIndex df1_multi_idx = pd.MultiIndex.from_frame(df1[['col1', 'col2']]) df2_multi_idx = pd.MultiIndex.from_frame(df2[['col1', 'col2']]) # 筛选df2中属于df1的行,提取索引 target_indexes = df2[df2_multi_idx.isin(df1_multi_idx)].index.tolist() print(target_indexes) # 输出: [0, 4, 5]
为什么这两种方案更高效?
你的原始方法用apply逐行拼接字符串,本质是Python层面的循环操作,在百万级数据下会非常缓慢。而上面的两种方案都是基于Pandas的矢量化操作,底层由C扩展实现,能充分利用CPU的并行处理能力,处理速度会提升几个数量级。
注意事项
- 务必确保用于匹配的列(
col1和col2)类型完全一致,比如你之前将col2转为字符串,两个DataFrame都要统一处理,否则会因为类型不匹配导致匹配失败。 - 如果df2中存在重复的匹配行,方案1中的
unique()可以避免返回重复索引;如果需要保留所有匹配行的索引(包括重复),去掉unique()即可。
内容的提问来源于stack exchange,提问作者bsmith
相关产品推荐
相关产品推荐

