如何不使用循环重排Pandas DataFrame,按组内位置依次排列
解决方法
先给每个PERIOD分组内的行添加一个组内序号,再按这个序号和PERIOD排序,就能得到你要的结果——全程不用循环,还能严格保持条目顺序:
步骤说明
- 新增组内序号列:用
groupby('PERIOD').cumcount()给每个PERIOD下的行从0开始计数,同一组里的第一行标记为0,第二行标记为1,以此类推。 - 按规则排序:先按组内序号升序排列,再按
PERIOD升序排列,就能实现「先取所有组的第一行,再取所有组的第二行」的效果。 - 移除辅助列:删掉新增的序号列,恢复原DataFrame的列结构。
代码实现
假设你的原始DataFrame名为df,代码如下:
import pandas as pd # 原始DataFrame df = pd.DataFrame({ 'PERIOD': [1,1,1,2,2,2,3,3,3], 'Value': [30,40,50,60,75,80,90,100,200] }) # 1. 添加组内序号列 df['group_idx'] = df.groupby('PERIOD').cumcount() # 2. 按组内序号和PERIOD排序 df_sorted = df.sort_values(by=['group_idx', 'PERIOD'], ignore_index=True) # 3. 删除辅助列 df_sorted = df_sorted.drop('group_idx', axis=1) print(df_sorted)
运行后输出结果完全匹配需求:
PERIOD Value 0 1 30 1 2 60 2 3 90 3 1 40 4 2 75 5 3 100 6 1 50 7 2 80 8 3 200
原理说明
groupby('PERIOD').cumcount()会为每个分组内的行生成连续序号,确保同一分组内的原始顺序不被打乱。按这个序号排序后,所有分组的第N行会被归为一组,再配合PERIOD升序,就完美实现了你要的排列逻辑。
内容的提问来源于stack exchange,提问作者S_Scouse
相关产品推荐
相关产品推荐

