簡體   English   中英

如何改組Pandas數據幀的行組?

[英]How to shuffle groups of rows of a Pandas dataframe?

我們假設我有一個數據幀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

如何將三乘三行的df排列,即如何隨后將第三行(0,1,2)隨機地隨機播放(第3,第4,第5),第3行(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

因此,新訂單具有來自原始數據幀的第二組3行,然后是最后一行,然后是第三組,最后是第一組。

你可以重塑為一個3D陣列,將第一個軸分成兩個,后者一個長度為3對應於組長度,然后使用np.random.shuffle沿第一個軸進行這樣的np.random.shuffle就地重排,長度很長因為團體數量占據了這些群體,從而達到了我們想要的結果,就像這樣 -

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

說明

為了給它一些解釋,讓我們使用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

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]]])

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]]])

然后,我們將這些值分配回輸入數據幀。

使用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

與@Divakar類似的解決方案,可能比我直接調整數據幀的索引更簡單:

import numpy as np
import pandas as pd

df = pd.DataFrame([np.arange(0, 12)]*4).T
len_group = 3

index_list = np.array(df.index)
np.random.shuffle(np.reshape(index_list, (-1, len_group)))

shuffled_df = df.loc[index_list, :]

樣本輸出:

shuffled_df
    Out[82]: 
     0   1   2   3
9    9   9   9   9
10  10  10  10  10
11  11  11  11  11
3    3   3   3   3
4    4   4   4   4
5    5   5   5   5
0    0   0   0   0
1    1   1   1   1
2    2   2   2   2
6    6   6   6   6
7    7   7   7   7
8    8   8   8   8

這與其他兩個答案的作用相同,但使用整數除法來創建組列。

nrows_df = len(df)
nrows_group = 3

shuffled = (
    df
    .assign(group_var=df.index // nrows_group)
    .set_index("group_var")
    .loc[np.random.permutation(nrows_df / nrows_group)]
)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM