对 pandas 数据框进行下采样,保持每个月相同比例的目标

问题描述 投票:0回答:1

我有一个 pandas 数据框

df
,其中
'TARGET'
列采用
0
1
的值,以及收集不同月份的
'MONTH'
列:

#_OBS_TARGET=0 #_OBS_TARGET=1
202207 44619 52960
202208 48093 55399
202209 50161 56528

我想对我的数据帧进行下采样,以获得与

TARGET = 0
TARGET = 1
对于
MONTH
的每个值具有相同数量的观察值:

#_OBS_TARGET=0 #_OBS_TARGET=1
202207 44619 44619
202208 48093 48093
202209 50161 50161

我尝试过以下内容

for m in df['MONTH'].unique():
    number_of_ones = len(df[(df['MONTH']==m) & (df['TARGET']==1)])
    number_of_zeros = len(df[(df['MONTH']==m) & (df['TARGET']==0)])
    n_obs_to_drop = number_of_ones - number_of_zeros 
    df[df['MONTH']==m].drop(df[(df['MONTH']==m) & (df['TARGET']==1)].sample(n_obs_to_drop).index, inplace = True)

但显然它并没有删除任何东西。

我该如何获取?也欢迎不同的方法。

请注意,

MONTH
的不同值中存在重复的索引值。
df
中还有更多列,应保留在下采样数据框中。

编辑:

我正在添加一个可重现的示例

import pandas as pd
data = {
"MONTH": [202207, 202207, 202207, 202207, 202208, 202208, 202208, 202209, 202209, 202209, 202209],
"TARGET": [1, 1, 0, 1, 1, 1, 0, 1, 0, 1, 0],
"other_column1": [10, 20, 30, 40, 50, 60, 70, 80, 90, 100, 110],  # Example additional columns
"other_column2": [100, 200, 300, 400, 500, 600, 700, 800, 900, 1000, 1100]
}
    
df = pd.DataFrame(data)

pd.crosstab(df['MONTH'],df['TARGET'])

TARGET  0   1
MONTH       
202207  1   3
202208  1   2
202209  2   2
python pandas dataframe data-manipulation downsampling
1个回答
0
投票

不确定这是否是最优雅的方式,但我会选择

获取每个月的样本数量

grp = pd.crosstab(df['MONTH'],df['TARGET'])\
    .min(1)\
    .reset_index(name='size')
    MONTH  size
0  202207     1
1  202208     1
2  202209     2

与原始 df 合并

df1 = pd.merge(df, grp)

使用之前定义的尺寸取样

df2 = df1.groupby(['MONTH', 'TARGET'])\
    .apply(lambda x: x.sample(n=x['size'].iloc[0]))\
    .reset_index(drop=True)
© www.soinside.com 2019 - 2024. All rights reserved.