按组随机播放pandas数据帧

时间:2017-08-09 08:50:20

标签: python pandas dataframe shuffle

我的数据框看起来像这样

sampleID  col1 col2
   1        1   63
   1        2   23
   1        3   73
   2        1   20
   2        2   94
   2        3   99
   3        1   73
   3        2   56
   3        3   34

我需要对数据帧进行混洗,将相同的样本放在一起,并且col1的顺序必须与上面的数据帧相同。

所以我需要它像这样

sampleID  col1 col2
   2        1   20
   2        2   94
   2        3   99
   3        1   73
   3        2   56
   3        3   34
   1        1   63
   1        2   23
   1        3   73

我该怎么做?如果我的例子不清楚请告诉我。

3 个答案:

答案 0 :(得分:4)

假设您要按sampleID进行随机播放。首先df.groupby,随机播放(import random优先),然后调用pd.concat

In [423]: groups = [df for _, df in df.groupby('sampleID')]

In [424]: random.shuffle(groups)

In [427]: pd.concat(groups).reset_index(drop=True)
Out[427]: 
   sampleID  col1  col2
0         2     1    20
1         2     2    94
2         2     3    99
3         1     1    63
4         1     2    23
5         1     3    73
6         3     1    73
7         3     2    56
8         3     3    34

您使用df.reset_index(drop=True)重置索引,但这是一个可选步骤。

答案 1 :(得分:1)

我发现这比公认的答案要快得多:

ids = df["sampleID"].unique()
random.shuffle(ids)
df = df.set_index("sampleID").loc[ids].reset_index()

由于某种原因,pd.concat是我的用例的瓶颈。无论采用哪种方式,都可以避免串联。

答案 2 :(得分:0)

只需在@ cs95答案中添加一件事即可。 如果您想按sampleID进行洗牌,但又想将sampleIDs从1开始排序。因此,这里sampleID的保留并不那么重要。 这是一个解决方案,您只需遍历扭曲的数据帧并更改sampleID

groups = [df for _, df in df.groupby('doc_id')]

random.shuffle(groups)

for i, df in enumerate(groups):
     df['doc_id'] = i+1

shuffled = pd.concat(groups).reset_index(drop=True)

        doc_id  sent_id  word_id
   0       1        1       20
   1       1        2       94
   2       1        3       99
   3       2        1       63
   4       2        2       23
   5       2        3       73
   6       3        1       73
   7       3        2       56
   8       3        3       34