
本文介绍一种高效、可扩展的方法,使用 numpy.argsort 构造稳定排序索引,将两个等长 DataFrame 按指定行数分组(如每 2 行为一块)交错拼接,避免循环和手动切片,代码简洁且支持任意分块大小。
本文介绍一种高效、可扩展的方法,使用 numpy.argsort 构造稳定排序索引,将两个等长 dataframe 按指定行数分组(如每 2 行为一块)交错拼接,避免循环和手动切片,代码简洁且支持任意分块大小。
在数据处理中,有时需要将两个结构一致的 DataFrame 按“块”而非单行进行交错合并——例如,取 df1 的前 2 行、紧接着 df2 的前 2 行,再取 df1 的第 3–4 行、再接 df2 的第 3–4 行,以此类推。这种模式常见于实验分组、时序对齐或批量结果整合场景。
Pandas 本身不提供原生的“块级交错拼接”方法,但可通过巧妙构造排序键实现:核心思想是为每个 DataFrame 的每一行分配一个逻辑“组号”,相同组号的行将被归并在一起,再利用 np.argsort 的稳定性(stable=True)保证组内原始顺序不变。
以下为标准实现(以每 2 行为一组):
import pandas as pd
import numpy as np
df1 = pd.DataFrame({'col': [1, 2, 3, 4]})
df2 = pd.DataFrame({'col': [5, 6, 7, 8]})
# 为 df1 和 df2 的每行生成组索引:[0,0,1,1] + [0,0,1,1]
group_ids = np.r_[
np.arange(len(df1)) // 2, # df1: [0,0,1,1]
np.arange(len(df2)) // 2 # df2: [0,0,1,1]
]
# 稳定排序:同组内保持原始顺序(df1 行优先于 df2 行,因先拼接 df1)
order = np.argsort(group_ids, stable=True)
# 先纵向拼接,再按 order 重排
result = pd.concat([df1, df2], ignore_index=False).iloc[order].reset_index(drop=True)
print(result)
输出:
col 0 1 1 2 2 5 3 6 4 3 5 4 6 7 7 8
✅ 关键点说明:
-
np.r_[]快速拼接两个数组;// 2实现每 2 行一个组(改为// N即可适配任意块大小); -
stable=True是必需的(NumPy ≥ 1.22),确保组内多行按原始拼接顺序排列(即df1的第 0 组两行总在df2同组两行之前); -
ignore_index=False保留原始索引,便于后续验证;若需连续整数索引,最后调用.reset_index(drop=True); - 该方法天然支持不同列名(需提前对齐列),也适用于多列 DataFrame(无需修改逻辑)。
⚠️ 注意事项:
- 两 DataFrame 行数应能被
N整除,否则末尾组会不完整(可提前截断或填充); - 若
df1与df2行数不等,需按最小公倍数或显式填充处理,否则group_ids长度不匹配; - 性能优异:时间复杂度 O(m+n),远优于循环切片 +
pd.concat的 O(k·(m+n))。
通过调整 N 值,即可灵活切换分块粒度——这是真正可复用的数据混洗模式,推荐收藏为常用工具片段。










