Python 分组后,熊猫为每组抽取不同的分数
现在从每个组中抽取样本,例如,我希望从组Python 分组后,熊猫为每组抽取不同的分数,python,pandas,group-by,sample-data,Python,Pandas,Group By,Sample Data,现在从每个组中抽取样本,例如,我希望从组b=1中抽取30%,从组b=0中抽取20%。我该怎么做? 如果我想要某个组的150%,我可以这样做吗?您可以从GroupBy对象中获取数据帧,例如,使用分组。获取组(0)。如果要从中采样,可以使用.sample方法。例如grouped.get_group(0)。示例(frac=0.2)给出: import pandas as pd df = pd.DataFrame({'a': [1,2,3,4,5,6,7], 'b
b=1
中抽取30%,从组b=0
中抽取20%。我该怎么做?
如果我想要某个组的150%,我可以这样做吗?您可以从GroupBy对象中获取数据帧,例如,使用
分组。获取组(0)
。如果要从中采样,可以使用.sample
方法。例如grouped.get_group(0)。示例(frac=0.2)
给出:
import pandas as pd
df = pd.DataFrame({'a': [1,2,3,4,5,6,7],
'b': [1,1,1,0,0,0,0],
})
grouped = df.groupby('b')
对于您给出的示例,两个示例将只给出一个元素,因为这些组有4个和3个元素,并且
0.2*4=0.8
和0.3*3=0.9
都是四舍五入到1。您可以动态返回随机样本数据帧,其中每个组定义的样本百分比不同。通过传递replace=True
,可以在百分比低于100%(参见示例1)和高于100%(参见示例2)的情况下执行此操作:
np.选择
,创建一个新列c
,该列返回根据您设置的20%、40%等百分比随机采样的每组行数.index
,并筛选带有.loc
的行以及列'a'、'b'
。代码grouped.apply(lambda x:x['c'].sample(frac=x['c'].iloc[0])
创建您正在查找的输出的多索引系列,但它需要一些清理。这就是为什么对我来说,获取.index
并使用.loc
过滤原始数据帧比尝试清理混乱的多索引系列更容易的原因如果您想使用现有Cv值的副本返回更大的随机样本,只需传递
replace=True
。然后,进行一些清理以获得输出
grouped = df.groupby('b', group_keys=False)
df['c'] = np.select([df['b'].eq(0), df['b'].eq(1)], [0.4, 0.2])
df.loc[grouped.apply(lambda x: x['c'].sample(frac=x['c'].iloc[0])).index, ['a','b']]
Out[1]:
a b
6 7 0
8 9 0
3 4 1
你说的20%和30%是什么意思?你是说你想从第0组中随机获得20%的项目,从第1组中随机获得30%的项目?您可以这样做,但由于您的组太小,因此对于此示例数据,每个组中只有一个项目。不确定有多少理由使用
np。请选择。您可以只执行df.loc[db.b==0,'c']=0.3
和其他组的类似操作。无需将分数转换为整数,因为sample
接受一个可以取一定比例的frac
参数。@BrenBarnnp。选择是因为存在多个条件.loc
是一种方式,但np。选择通常适用于多种情况。您必须在多行代码上编写.loc
。这没什么错。这只是一种不同的方法。我喜欢你的。尽管如此,我还是喜欢你的组(0)
代码。@BrenBarn Nvmd,我明白你现在使用frac
的意思了。谢谢但是,如果指定一个frac
>1,则这不起作用。我认为这也使得np.select
比.loc
在我看来更干净一点。.reset\u index().rename({'index':'a'},axis=1)
做什么@DavidErickson@user14862671这就是使用reset\u index()
时发生的情况。尝试:。重命名({'level_1':'a'},axis=1))
而不是。重命名({'index':'a'},axis=1))
grouped = df.groupby('b', group_keys=False)
df['c'] = np.select([df['b'].eq(0), df['b'].eq(1)], [0.4, 0.2])
df.loc[grouped.apply(lambda x: x['c'].sample(frac=x['c'].iloc[0])).index, ['a','b']]
Out[1]:
a b
6 7 0
8 9 0
3 4 1
grouped = df.groupby('b', group_keys=False)
v = df['b'].value_counts()
df['c'] = np.select([df['b'].eq(0), df['b'].eq(1)],
[int(v.loc[0] * 1.2), int(v.loc[1] * 2)]) #frac parameter doesn't work with sample when frac > 1, so we have to calcualte the integer value for number of rows to be sampled.
(grouped.apply(lambda x: x['b'].sample(x['c'].iloc[0], replace=True))
.reset_index()
.rename({'index' : 'a'}, axis=1))
Out[2]:
a b
0 7 0
1 8 0
2 9 0
3 7 0
4 7 0
5 8 0
6 1 1
7 3 1
8 3 1
9 1 1
10 0 1
11 0 1
12 4 1
13 2 1
14 3 1
15 0 1