超过 2 个类的下采样

Gio*_*Gio 0 python downsampling pandas

我正在创建一个简单的代码,当您的目标变量具有 2 个以上的类时,它允许对数据帧进行下采样。

df我们的任意数据集和'TARGET_VAR'一个具有 2 个以上类的分类变量。

import pandas as pd
label='TARGET_VAR' #define the target variable

num_class=df[label].value_counts() #creates list with the count of each class value
temp=pd.DataFrame() #create empty dataframe to be filled up

for cl in num_class.index: #loop through classes
    #iteratively downsample every class according to the smallest
    #class 'min(num_class)' and append it to the dataframe.
    temp=temp.append(df[df[label]==cl].sample(min(num_class)))

df=temp #redefine initial dataframe as the subsample one

del temp, num_class #delete temporary dataframe
Run Code Online (Sandbox Code Playgroud)

现在我想知道,有没有办法以更精致的方式做到这一点?例如,无需创建临时数据集?我试图找出一种方法来“矢量化”多个类的操作,但没有取得任何进展。下面是我的想法,可以很容易地为 2 个类实现,但我不知道如何将它扩展到多个类的情况。

如果您有 2 个课程,这非常有效

 df= pd.concat([df[df[label]==num_class.idxmin()],\
 df[df[label]!=num_class.idxmin()].sample(min(num_class))])
Run Code Online (Sandbox Code Playgroud)

这允许您为其他类选择正确数量的观察,但这些类不一定具有相同的表示。

 df1= pd.concat([df[df[label]==num_class.idxmin()],\
 df[df[label]!=num_class.idxmin()].sample(min(num_class)*(len(num_class)-1))])
Run Code Online (Sandbox Code Playgroud)

Gus*_*eca 5

你可以尝试类似的东西:

label='TARGET_VAR'

g = df.groupby(label, group_keys=False)
balanced_df = pd.DataFrame(g.apply(lambda x: x.sample(g.size().min()))).reset_index(drop=True)
Run Code Online (Sandbox Code Playgroud)

我相信这会产生您想要的结果,请随时提出任何进一步的问题。

编辑

根据OP的建议修复了代码。