如何在Pandas中按组对DataFrame进行行级交错排列?
DataFrame组内行级交错排列的实现思路
假设我们有如下示例DataFrame:
import pandas as pd df = pd.DataFrame({ 'Group': ['A', 'A', 'A', 'B', 'B', 'B'], 'Score': [10, 20, 30, 15, 25, 35] })
目标是将其转换为A组第1行→B组第1行→A组第2行→B组第2行→... 的交错排列形式,以下是几种可行的实现思路:
方法1:添加组内序号后排序
这是最直观且通用的方法,适用于任意组数(只要每组行数一致):
# 给每个组内的行分配递增序号 df['row_num'] = df.groupby('Group').cumcount() # 先按组内序号排序,再按分组排序,实现交错 result = df.sort_values(by=['row_num', 'Group']) \ .drop('row_num', axis=1) \ .reset_index(drop=True)
核心逻辑:通过cumcount()标记每组内的行位置,再以这个位置为第一排序键,确保同位置的行被排在一起,最后按分组排序实现交错。
方法2:拆分分组后逐行拼接
适合分组数量明确且较少的场景(比如只有2组),逻辑清晰易调试:
# 拆分出各个分组并重置索引,保证行号对齐 group_a = df[df['Group'] == 'A'].reset_index(drop=True) group_b = df[df['Group'] == 'B'].reset_index(drop=True) # 逐行配对并添加到结果列表 interleaved_rows = [] for a_row, b_row in zip(group_a.itertuples(index=False), group_b.itertuples(index=False)): interleaved_rows.append(a_row) interleaved_rows.append(b_row) # 转换为DataFrame result = pd.DataFrame(interleaved_rows, columns=df.columns)
如果是多组(比如3组A/B/C),可以嵌套循环或用itertools.product扩展逻辑。
方法3:透视+逆透视重塑数据
利用pandas的透视表功能,适合多分组且每组行数一致的场景:
# 添加组内序号 df['row_num'] = df.groupby('Group').cumcount() # 透视成宽表:每行对应一个组内序号,每列对应一个分组的Score pivot_df = df.pivot(index='row_num', columns='Group', values='Score').reset_index() # 逆透视转回长表,同时保留分组信息 melted_df = pivot_df.melt( id_vars='row_num', value_vars=['A', 'B'], var_name='Group', value_name='Score' ) # 排序后清理临时列 result = melted_df.sort_values(by=['row_num', 'Group']) \ .drop('row_num', axis=1) \ .reset_index(drop=True)
这种方法本质是通过数据结构的转换,让同位置的行自动对齐,再转回长表实现交错。
方法4:利用numpy数组重组(高性能)
适合处理大型数据集,借助numpy的矢量运算提升效率:
# 先确保数据按分组连续排列 sorted_df = df.sort_values(by=['Group']).reset_index(drop=True) # 假设每组有n行(这里n=3),分组数为g(这里g=2) n = sorted_df['Group'].value_counts().iloc[0] g = sorted_df['Group'].nunique() # 转换为numpy数组,重组形状后转平 arr = sorted_df.to_numpy() \ .reshape(g, n, -1) \ .transpose(1, 0, 2) \ .ravel() \ .reshape(-1, sorted_df.shape[1]) # 转回DataFrame result = pd.DataFrame(arr, columns=df.columns)
核心逻辑:将数据重组为「分组数×每组行数×列数」的三维数组,转置后让同位置的行处于同一维度,最后拉平成二维数组,性能比纯pandas操作快很多。
内容的提问来源于stack exchange,提问作者David Davíd
相关产品推荐
相关产品推荐

