如何基于两个大DataFrame高效合并指定多行生成新DataFrame?
高效合并Pandas DataFrame的向量化方案
核心思路
通过分组标记+批量拼接替代逐行循环,利用Pandas内置的groupby优化操作实现高效处理,彻底规避iterrows()的性能瓶颈。
实现步骤
1. 准备示例数据
import pandas as pd import numpy as np # 构建df1 mylist = [ {'1': 'A', '2': 'B','3':'1'}, {'1': 'C', '2': 'D','3':pd.NA}, {'1': 'E', '2': 'F','3':'3'}, {'1': 'G', '2': pd.NA,'3':'4'}, {'1': 'I', '2': 'J','3':'5'}] df1 = pd.DataFrame(mylist) # 构建df2 info_list = [{'n':2},{'n':2}] df2 = pd.DataFrame(info_list,index=[0,2])
2. 生成分组标记
为df1的每一行标记对应的目标合并行索引:
- 属于df2指定合并范围的行,标记为起始索引
- 未被覆盖的行,标记为自身索引
# 初始化目标索引数组 target_idx = np.full(len(df1), fill_value=-1) # 标记df2指定的合并范围 for start, n in df2.itertuples(): end = start + n target_idx[start:end] = start # 处理未被覆盖的行 mask = target_idx == -1 target_idx[mask] = df1.index[mask]
3. 分组拼接生成结果
按标记的目标索引分组,将每组内的行横向拼接,最后重命名列:
# 分组后横向拼接每组的行 df3 = df1.groupby(target_idx).apply( lambda x: pd.Series(x.values.flatten()) ).reset_index(level=1, drop=True) # 重命名列(从1开始连续编号) df3.columns = [str(i+1) for i in df3.columns]
最终输出
1 2 3 4 5 6 0 A B 1 C D <NA> 2 E F 3 G <NA> 4 4 I J 5 NaN NaN NaN
性能优势
- 避免
iterrows()的逐行循环开销,groupby操作由Pandas底层优化实现,处理大型DataFrame时速度提升显著 - 整体时间复杂度为O(N)(N为df1行数),远优于循环方案的O(N*K)(K为每组平均行数)
内容的提问来源于stack exchange,提问作者Blake Redwine
相关产品推荐
相关产品推荐

