【问题标题】:Balanced sampling with python使用python进行平衡采样
【发布时间】:2020-10-23 08:32:30
【问题描述】:

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

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

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

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

【问题讨论】:

  • 完整数据框中“e”和“p”行的频率是否也是50%?

标签: python dataframe sampling


【解决方案1】:

如果数据框是这样的:

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)]

【讨论】:

    【解决方案2】:

    这取决于你在完整数据集中拥有的“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]
    

    【讨论】:

    • 它应该可以工作,但我的问题不是用 70% 的随机行和相同数量的 e 和 p 行创建第一个 df。但是要创建具有剩余行的第二个!
    • 我已经更新了我的答案,它也为您提供了剩余的数据。
    猜你喜欢
    • 1970-01-01
    • 2022-11-15
    • 1970-01-01
    • 2020-03-11
    • 1970-01-01
    • 2014-06-20
    • 2014-06-08
    • 2020-09-06
    • 2020-08-30
    相关资源
    最近更新 更多