2016-06-21 147 views
1

随机样本的我有一个熊猫数据帧这样说:Python的熊猫:获得2套每

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

您可以随机选择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

是的,我喜欢这个优于我的答案,更清洁,但我认为适用是不必要的。我认为你可以对整个DataFrame进行采样并像往常一样进行分组:'df.sample(len(df))。groupby('user')。head(1)'。 –

+1

是的,'df.sample(len(df))'可能在引擎盖下做了同样的事情(索引的随机排列)。但我认为原始数据帧可能很大,因此创建另一个长度相同的数据帧可能不是最佳的。 – ayhan

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 

希望这会有所帮助。