我有一个与此类似的dataFrame,但有数千个值:
import numpy as np
import pandas as pd
# Setup fake data.
np.random.seed([3, 1415])
df = pd.DataFrame({
'Class': list('AAAAAAAAAABBBBBBBBBB'),
'type': (['short']*5 + ['long']*5) *2,
'image name': (['image01']*2 + ['image02']*2)*5,
'Value2': np.random.random(20)})
我能够找到一种方法,对每个图像,每个类和每个类型随机抽样2个值,使用以下代码:
df2 = df.groupby(['type', 'Class', 'image name'])[['Value2']].apply(lambda s: s.sample(min(len(s),2)))
我得到了以下结果:
我正在寻找一种方法来对该表进行子集化,以便能够为每个类型和每个类随机选择一个随机图像(“图像名称”)(并保留随机选择图像的2个值。
Excel我想要的输出示例:
答案 0 :(得分:0)
IIUC ,问题在于您不希望对列image name
进行分组,但如果该列未包含在groupby中,您将失去此列
您可以先创建grouby对象
gb = df.groupby(['type', 'Class'])
现在,您可以使用list comprehesion
来交换grouby块blocks = [data.sample(n=1) for _,data in gb]
现在,您可以连接块,重建随机采样的数据帧
pd.concat(blocks)
输出
Class Value2 image name type
7 A 0.817744 image02 long
17 B 0.199844 image01 long
4 A 0.462691 image01 short
11 B 0.831104 image02 short
或强>
您可以修改代码并将列image name
添加到群组中,就像这样
df.groupby(['type', 'Class'])[['Value2','image name']].apply(lambda s: s.sample(min(len(s),2)))
Value2 image name
type Class
long A 8 0.777962 image01
9 0.757983 image01
B 19 0.100702 image02
15 0.117642 image02
short A 3 0.465239 image02
2 0.460148 image02
B 10 0.934829 image02
11 0.831104 image02
编辑:每组保持图像相同
我不确定您是否可以避免使用迭代过程来解决此问题。您可以循环遍历groupby块,过滤组随机图像并保持每组相同的名称,然后从剩余的图像中随机采样,如下所示
import random
gb = df.groupby(['Class','type'])
ls = []
for index,frame in gb:
ls.append(frame[frame['image name'] == random.choice(frame['image name'].unique())].sample(n=2))
pd.concat(ls)
输出
Class Value2 image name type
6 A 0.850445 image02 long
7 A 0.817744 image02 long
4 A 0.462691 image01 short
0 A 0.444939 image01 short
19 B 0.100702 image02 long
15 B 0.117642 image02 long
10 B 0.934829 image02 short
14 B 0.721535 image02 short