python均衡采样

问题描述

我有23列和8124行的df。在第一列(命名类型)中,只有两个值“ e”或“ p”。 现在,我需要创建两个不同的df:

  • 一个df必须包含5686行(大约占行的70%),并且同时“ e”和“ p”的数目必须相同(e的50%和p的50%)。
  • 第二个df必须包含其余行。

重要的是,所有这些行都必须由原始df随机选择(不允许重复)。

编辑:元素e和p的行不足,所以我不得不牺牲一些距离

解决方法

这取决于完整数据集中“ e”和“ p”的比例。如果'e'或'p'中的任何一个均小于2843(5686的50%),则您将无法实现,前提是您满足此条件,则可以尝试以下操作:

filtered_data = df.groupby(['Col_with_e_and_p']).apply(lambda x: x.sample(n=2843)).reset_index(drop = True)

对于剩余数据,您可以使用此解决方法,因为将原始索引分组之后:

bool_position = df.merge(filtered_data,how='left',indicator=True)['_merge'].str.contains('left_only')
remaining_df = df[bool_position]
,

如果数据帧是这样的:

import pandas as pd
import numpy as np

df = pd.DataFrame(np.random.uniform(0,1,(8124,23)))
df.insert(0,"x",np.random.choice(['e','p'],8124))

如果您事先知道数字,则一种方法是使用列表推导来获取'e'的1/2和'p'的1/2的索引。然后使用以下子集数据框:

n = (np.floor(0.7*df.shape[0])/2).astype('int')
2843

idx = np.array([np.random.choice(df.index[df['x']==i],n,replace=False)  for i in ['p','e']]).flatten()

df1 = df.iloc[idx]
df2 = df.iloc[~df.index.isin(idx)]