基于自定义迭代序号对齐合并多个 DataFrame 的完整教程

2次阅读

基于自定义迭代序号对齐合并多个 DataFrame 的完整教程

本文介绍如何根据用户指定的 iteration 字符串列表,分别从多个 dataframe 中提取对应行并横向拼接,实现灵活、可控的跨表对齐合并,适用于性能测试数据对比等场景。

在实际数据分析(尤其是存储/数据库性能测试)中,常需将不同轮次、不同配置下的指标(如 IOPS、延迟)按特定 iteration 标识进行横向比对。但这些 iteration 值往往不完全一致,也无法直接使用 merge 或 join 的默认逻辑(如 inner/outer)。此时,按用户定义的顺序与索引显式对齐成为关键需求。

pandas 提供了高效且可复用的解决方案:通过 set_index → reindex → reset_index 三步完成“按指定顺序拉取并保持对齐”,再结合 pd.concat(…, axis=1) 实现列方向拼接。

✅ 核心实现步骤

  1. 定义对齐函数:将 iteration 设为索引,按目标列表重排行序(缺失项自动填充 NaN),最后恢复 iteration 为普通列;
  2. 分别对齐各 DataFrame:传入各自对应的 iteration 列表;
  3. 水平拼接结果:使用 axis=1 将对齐后的 DataFrame 并排组合。
import pandas as pd  def align(df, lst):     return (df.set_index('iteration')               .reindex(lst)  # 严格按 lst 顺序取行,缺失则为 NaN               .reset_index())  # 示例数据(已简化) df1 = pd.DataFrame({     'iteration': ['1_1', '2_2', '3_3', '4_4', '5_5', '6_6', '7_7', '8_8', '9_9'],     'IOPS': [46090, 12, 49164, 98311, 196604, 249843, 298974, 348108, 397230],     'Latency': [0.7300, 0.0221, 0.1236, 0.1318, 0.2076, 0.1467, 0.1578, 0.1604, 0.1707] })  df2 = pd.DataFrame({     'iteration': ['1_1', '2_2', '3_3', '4_4', '5_5', '6_6'],     'IOPS': [46074, 12, 49159, 98307, 298976, 397265],     'Latency': [0.6977, 0.0279, 0.1921, 0.2189, 0.2337, 0.2622] })  # 按需指定每张表要提取的 iteration 序列 out = pd.concat([     align(df1, ['1_1', '2_2', '3_3', '9_9']),     align(df2, ['1_1', '2_2', '5_5', '6_6']) ], axis=1)  print(out)

输出结果

iteration    IOPS  Latency iteration    IOPS  Latency 0       1_1   46090   0.7300       1_1   46074   0.6977 1       2_2      12   0.0221       2_2      12   0.0279 2       3_3   49164   0.1236       5_5  298976   0.2337 3       9_9  397230   0.1707       6_6  397265   0.2622

? 注意:reindex 保证输出行数等于目标列表长度,且严格按列表顺序排列;若某 iteration 在原始 DataFrame 中不存在,对应位置将为 NaN(可根据需要后续用 fillna() 处理)。

? 扩展:批量处理多个 DataFrame

当涉及 3 个及以上 DataFrame 时,推荐使用 itertools.starmap + zip 统一调度,提升代码可维护性:

from itertools import starmap  dfs = [df1, df2]  # 待处理的 DataFrame 列表 iters = [     ['1_1', '2_2', '3_3', '9_9'],  # df1 对应的 iteration     ['1_1', '2_2', '5_5', '6_6']   # df2 对应的 iteration ]  out = pd.concat(starmap(align, zip(dfs, iters)), axis=1)

⚠️ 注意事项与最佳实践

  • 确保 iteration 列类型一致:避免因字符串/数字混用导致匹配失败(建议统一为 str);
  • 检查重复值:若 iteration 在某 DataFrame 中存在重复,set_index 会引发 ValueError,需先去重或聚合;
  • 列名冲突管理:若多个 DataFrame 含有同名列(非 iteration),拼接后将自动添加 .x, .y 后缀;如需自定义,可在 align() 内重命名列(例如 df.rename(columns={‘IOPS’: ‘IOPS_df1’}));
  • 性能提示:对超大表,reindex 比 isin + loc 更高效,因其底层基于哈希索引查找。

掌握该模式后,你不仅能精准比对任意子集的测试结果,还可轻松扩展至多工具、多环境、多参数组合的自动化分析流水线。

text=ZqhQzanResources