按 n 行的块反转行的顺序

Reverse the order of the rows by chunks of n rows

考虑以下序列:

df = pd.DataFrame(np.random.randint(0,100,size=(100, 4)), columns=list('ABCD'))

产生:

     A   B   C   D
0   56  83  99  46
1   40  70  22  51
2   70   9  78  33
3   65  72  79  87
4    0   6  22  73
..  ..  ..  ..  ..
95  35  76  62  97
96  86  85  50  65
97  15  79  82  62
98  21  20  19  32
99  21   0  51  89

我可以使用以下命令反转顺序:

df.iloc[::-1]

这给了我以下结果:

     A   B   C   D
99  21   0  51  89
98  21  20  19  32
97  15  79  82  62
96  86  85  50  65
95  35  76  62  97
..  ..  ..  ..  ..
4    0   6  22  73
3   65  72  79  87
2   70   9  78  33
1   40  70  22  51
0   56  83  99  46

如果我想每第 n 行反转一次序列,我将如何重写代码,例如每 4 行?

IIUC,你想按块(3, 2, 1, 0, 8, 7, 6, 5…)反转:

一种选择是将 groupby 与自定义组一起使用:

N = 4

group = df.index//N

# if the index is not a linear range
# import numpy as np
# np.arange(len(df))//N

df.groupby(group).apply(lambda d: d.iloc[::-1]).droplevel(0)

输出:

     A   B   C   D
3   45  33  73  77
2   91  34  19  68
1   12  25  55  19
0   65  48  17   4
7   99  99  95   9
..  ..  ..  ..  ..
92  89  68  48  67
99  99  28  52  87
98  47  49  21   8
97  80  18  92   5
96  49  12  24  40

[100 rows x 4 columns]

一种仅基于索引的非常快速的方法是使用 numpy 生成由块反转的索引列表:

import numpy as np

N = 4
idx = np.arange(len(df)).reshape(-1, N)[:, ::-1].ravel()
# array([ 3,  2,  1,  0,  7,  6,  5,  4, 11, ...])

# slice using iloc
df.iloc[idx]