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