注意:这个问题与答案不一样:"Pandas:在groupby之后对每个组进行抽样"
试图弄清楚如何使用pandas.DataFrame.sample或任何其他功能来平衡这些数据:
df[class].value_counts()
c1 9170
c2 5266
c3 4523
c4 2193
c5 1956
c6 1896
c7 1580
c8 1407
c9 1324
Run Code Online (Sandbox Code Playgroud)
我需要得到每个类(c1,c2,.. c9)的随机样本,其中样本大小等于具有最小实例数的类的大小.在此示例中,样本大小应为类c9 = 1324的大小.
用熊猫做任何简单的方法吗?
更新
为澄清我的问题,请在上表中:
c1 9170
c2 5266
c3 4523
...
Run Code Online (Sandbox Code Playgroud)
数字是c1,c2,c3,...类的实例计数,因此实际数据如下所示:
c1 'foo'
c2 'bar'
c1 'foo-2'
c1 'foo-145'
c1 'xxx-07'
c2 'zzz'
...
Run Code Online (Sandbox Code Playgroud)
等等
更新2
澄清更多:
d = {'class':['c1','c2','c1','c1','c2','c1','c1','c2','c3','c3'],
'val': [1,2,1,1,2,1,1,2,3,3]
}
df = pd.DataFrame(d)
class val
0 c1 1
1 c2 2
2 c1 1
3 c1 1
4 c2 2
5 c1 1
6 c1 1
7 c2 2
8 c3 3
9 c3 3
df['class'].value_counts()
c1 5
c2 3
c3 2
Name: class, dtype: int64
g = df.groupby('class')
g.apply(lambda x: x.sample(g.size().min()))
class val
class
c1 6 c1 1
5 c1 1
c2 4 c2 2
1 c2 2
c3 9 c3 3
8 c3 3
Run Code Online (Sandbox Code Playgroud)
看起来像这样.主要问题:
怎么样g.apply(lambda x: x.sample(g.size().min()))?我知道'lambda`是什么,但是:
lambda在x这种情况下?g在g.size()?piR*_*red 15
g = df.groupby('class')
g.apply(lambda x: x.sample(g.size().min()).reset_index(drop=True)
class val
0 c1 1
1 c1 1
2 c2 2
3 c2 2
4 c3 3
5 c3 3
Run Code Online (Sandbox Code Playgroud)
您的后续问题的答案
x在lambda最终被一个数据帧是子集df由所述基团表示.这些数据帧中的每一个,每个组都有一个,通过它lambda.g是groupby对象.我把它放在一个命名变量中因为我打算两次使用它. df.groupby('class').size()是另一种方法,df['class'].value_counts()但是因为groupby无论如何,我不得不重复使用它groupby,使用a size来获取值计数...节省时间.df采样的指数值.我添加reset_index(drop=True)了摆脱它.上面的答案是正确的,但我很想指定上面的g不是Pandas DataFrame用户最可能想要的对象。它是一个pandas.core.groupby.groupby.DataFrameGroupBy对象。看到这一点,尝试调用head上摹,结果将是如下图所示。
import pandas as pd
d = {'class':['c1','c2','c1','c1','c2','c1','c1','c2','c3','c3'],
'val': [1,2,1,1,2,1,1,2,3,3]
}
d = pd.DataFrame(d)
g = d.groupby('class')
g.apply(lambda x: x.sample(g.size().min()).reset_index(drop=True))
g.head()
>>> class val
0 c1 1
1 c2 2
2 c1 1
3 c1 1
4 c2 2
5 c1 1
6 c1 1
7 c2 2
8 c3 3
9 c3 3
Run Code Online (Sandbox Code Playgroud)
为了解决这个问题,我们需要在将数据分组之后将g转换为a Pandas DataFrame,如下所示:
g = d.groupby('class')
g = pd.DataFrame(g.apply(lambda x: x.sample(g.size().min()).reset_index(drop=True)))
Run Code Online (Sandbox Code Playgroud)
现在调用head将产生:
g.head()
>>>class val
0 c1 1
1 c2 2
2 c1 1
3 c1 1
4 c2 2
Run Code Online (Sandbox Code Playgroud)
用户最想要的是哪个。
小智 5
该方法随机获取每个类的k个元素。
def sampling_k_elements(group, k=3):
if len(group) < k:
return group
return group.sample(k)
balanced = df.groupby('class').apply(sampling_k_elements).reset_index(drop=True)
Run Code Online (Sandbox Code Playgroud)