如何打乱 Pandas 数据帧的行组?

Arc*_*hie 5 python numpy shuffle pandas

假设我有一个数据框 df:

import numpy as np
import pandas as pd

df = pd.DataFrame(np.random.rand(12,4))

print(df)

     0   1   2   3
0   71  64  84  20
1   48  60  83  61
2   48  78  71  46
3   65  88  66  77
4   71  22  42  58
5   66  76  64  80
6   67  28  74  87
7   32  90  55  78
8   80  42  52  14
9   54  76  73  17
10  32  89  42  36
11  85  78  61  12
Run Code Online (Sandbox Code Playgroud)

如何将 df 的行三行打乱,即,如何将前三行 (0, 1, 2) 与第二行 (3, 4, 5), 第三行 (6, 7, 8) 还是第四组 (9, 10, 11)?这可能是一个可能的结果:

print(df)

     0   1   2   3
3   65  88  66  77
4   71  22  42  58
5   66  76  64  80
9   54  76  73  17
10  32  89  42  36
11  85  78  61  12
6   67  28  74  87
7   32  90  55  78
8   80  42  52  14
0   71  64  84  20
1   48  60  83  61
2   48  78  71  46
Run Code Online (Sandbox Code Playgroud)

因此,新订单具有3来自原始数据帧的第二组行,然后是最后一组,然后是第三组,最后是第一组。

Div*_*kar 5

您可以重塑为一个3D数组,将第一个轴分成两个,后者的长度3与组长度相对应,然后np.random.shuffle用于沿第一个轴的这种分组就地洗牌,其长度为组的数量。组,从而达到我们想要的结果,就像这样 -

np.random.shuffle(df.values.reshape(-1,3,df.shape[1]))
Run Code Online (Sandbox Code Playgroud)

解释

为了给它一些解释,让我们使用np.random.permutation沿着第一个轴生成那些随机索引,然后索引到3D数组版本。

1]输入df:

In [199]: df
Out[199]: 
     0   1   2   3
0   71  64  84  20
1   48  60  83  61
2   48  78  71  46
3   65  88  66  77
4   71  22  42  58
5   66  76  64  80
6   67  28  74  87
7   32  90  55  78
8   80  42  52  14
9   54  76  73  17
10  32  89  42  36
11  85  78  61  12
Run Code Online (Sandbox Code Playgroud)

2]获取3D阵列版本:

In [200]: arr_3D = df.values.reshape(-1,3,df.shape[1])

In [201]: arr_3D
Out[201]: 
array([[[71, 64, 84, 20],
        [48, 60, 83, 61],
        [48, 78, 71, 46]],

       [[65, 88, 66, 77],
        [71, 22, 42, 58],
        [66, 76, 64, 80]],

       [[67, 28, 74, 87],
        [32, 90, 55, 78],
        [80, 42, 52, 14]],

       [[54, 76, 73, 17],
        [32, 89, 42, 36],
        [85, 78, 61, 12]]])
Run Code Online (Sandbox Code Playgroud)

3]获取混洗索引和索引到3D版本的第一个轴:

In [202]: shuffle_idx = np.random.permutation(arr_3D.shape[0])

In [203]: shuffle_idx
Out[203]: array([0, 3, 1, 2])

In [204]: arr_3D[shuffle_idx]
Out[204]: 
array([[[71, 64, 84, 20],
        [48, 60, 83, 61],
        [48, 78, 71, 46]],

       [[54, 76, 73, 17],
        [32, 89, 42, 36],
        [85, 78, 61, 12]],

       [[65, 88, 66, 77],
        [71, 22, 42, 58],
        [66, 76, 64, 80]],

       [[67, 28, 74, 87],
        [32, 90, 55, 78],
        [80, 42, 52, 14]]])
Run Code Online (Sandbox Code Playgroud)

然后,我们将这些值分配回输入数据帧。

使用np.random.shuffle,我们只是在原地做所有事情,并隐藏了显式生成混洗索引和分配回所需的工作。

样品运行 -

In [181]: df = pd.DataFrame(np.random.randint(11,99,(12,4)))

In [182]: df
Out[182]: 
     0   1   2   3
0   82  49  80  20
1   19  97  74  81
2   62  20  97  19
3   36  31  14  41
4   27  86  28  58
5   38  68  24  83
6   85  11  25  88
7   21  31  53  19
8   38  45  14  72
9   74  63  40  94
10  69  85  53  81
11  97  96  28  29

In [183]: np.random.shuffle(df.values.reshape(-1,3,df.shape[1]))

In [184]: df
Out[184]: 
     0   1   2   3
0   85  11  25  88
1   21  31  53  19
2   38  45  14  72
3   82  49  80  20
4   19  97  74  81
5   62  20  97  19
6   36  31  14  41
7   27  86  28  58
8   38  68  24  83
9   74  63  40  94
10  69  85  53  81
11  97  96  28  29
Run Code Online (Sandbox Code Playgroud)