Python Pandas:每组获取2组随机样本

时间:2016-06-21 09:32:37

标签: python pandas

我有一个pandas DataFrame这样说:

   user  value
0     a      1
1     a      2
2     a      3
3     a      4
4     a      5
5     b      6
6     b      7
7     b      8
8     b      9
9     b     10
10    c     11
11    c     12
12    c     13
13    c     14
14    c     15

现在我想按用户分组,并从中创建两个互斥的随机样本,例如

Set1每组1个样本:

   user  value
3     a      4
9     b     10
13    c     14

Set2,每组2个样本:

   user  value
0     a      1
1     a      2
5     b      6
6     b      7
10    c     11
11    c     12

到目前为止,我试过这个:

u = np.array(['a','b','c'])
u = np.repeat(u,5)
df = pd.DataFrame({'user':u,'value':[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15]})

set1  = df.groupby(['user']).tail(1)
set2  = df.groupby(['user']).head(2)

但这些不是随机样本,我希望它们是互斥的。有什么想法吗?

PS。每组始终至少有3个元素

3 个答案:

答案 0 :(得分:4)

您可以为每个用户随机选择3条记录:

a = df.groupby("user")["value"].apply(lambda x: x.sample(3))

a
Out[27]: 
user    
a     3      4
      0      1
      2      3
b     5      6
      7      8
      6      7
c     14    15
      10    11
      13    14
dtype: int64

并将第一组分配给第一组,其余两组分配给第二组:

a.groupby(level=0).head(1)
Out[28]: 
user    
a     3      4
b     5      6
c     14    15
dtype: int64

a.groupby(level=0).tail(2)
Out[29]: 
user    
a     0      1
      2      3
b     7      8
      6      7
c     10    11
      13    14
dtype: int64

答案 1 :(得分:2)

这可能有点天真,但我所做的只是重新索引DataFrame,随机排列DataFrame的长度并重置索引。在那之后我像你原来的代码一样采取头部和尾部,似乎工作。这可能会成为一个函数:

a = np.arange(len(df))
np.random.shuffle(a)
df = df.reindex(a).reset_index()

set1  = df.groupby(['user']).tail(1)
>>> 
    index user  value
12      9    b     10
13     10    c     11
14      1    a      2

set2  = df.groupby(['user']).head(2)
>>>
   index user  value
0      6    b      7
1      2    a      3
2      5    b      6
3     13    c     14
4      3    a      4
6     12    c     13

希望这有帮助。

答案 2 :(得分:1)

可能有一个更好的解决方案,但是在分组之前随机化数据然后每组采用尾部和头部呢?您可以获取一组索引,对其进行随机排列并使用它来创建新的加扰数据帧,然后执行当前过程。