Python 分组后,熊猫为每组抽取不同的分数

Python 分组后,熊猫为每组抽取不同的分数,python,pandas,group-by,sample-data,Python,Pandas,Group By,Sample Data,现在从每个组中抽取样本,例如,我希望从组b=1中抽取30%,从组b=0中抽取20%。我该怎么做? 如果我想要某个组的150%,我可以这样做吗?您可以从GroupBy对象中获取数据帧,例如,使用分组。获取组(0)。如果要从中采样,可以使用.sample方法。例如grouped.get_group(0)。示例(frac=0.2)给出: import pandas as pd df = pd.DataFrame({'a': [1,2,3,4,5,6,7], 'b

现在从每个组中抽取样本,例如,我希望从组
b=1
中抽取30%,从组
b=0
中抽取20%。我该怎么做?
如果我想要某个组的150%,我可以这样做吗?

您可以从GroupBy对象中获取数据帧,例如,使用
分组。获取组(0)
。如果要从中采样,可以使用
.sample
方法。例如
grouped.get_group(0)。示例(frac=0.2)
给出:

import pandas as pd

df = pd.DataFrame({'a': [1,2,3,4,5,6,7],
                   'b': [1,1,1,0,0,0,0],
})

grouped = df.groupby('b')

对于您给出的示例,两个示例将只给出一个元素,因为这些组有4个和3个元素,并且
0.2*4=0.8
0.3*3=0.9
都是四舍五入到1。

您可以动态返回随机样本数据帧,其中每个组定义的样本百分比不同。通过传递
replace=True
,可以在百分比低于100%(参见示例1)和高于100%(参见示例2)的情况下执行此操作:

  • 使用
    np.选择
    ,创建一个新列
    c
    ,该列返回根据您设置的20%、40%等百分比随机采样的每组行数
  • 在此基础上,您可以根据这些百分比条件对每组进行x行采样。从这些行中,返回行的
    .index
    ,并筛选带有
    .loc
    的行以及列
    'a'、'b'
    。代码
    grouped.apply(lambda x:x['c'].sample(frac=x['c'].iloc[0])
    创建您正在查找的输出的多索引系列,但它需要一些清理。这就是为什么对我来说,获取
    .index
    并使用
    .loc
    过滤原始数据帧比尝试清理混乱的多索引系列更容易的原因

  • 如果您想使用现有Cv值的副本返回更大的随机样本,只需传递
    replace=True
    。然后,进行一些清理以获得输出

    grouped = df.groupby('b', group_keys=False)
    df['c'] = np.select([df['b'].eq(0), df['b'].eq(1)], [0.4, 0.2])
    df.loc[grouped.apply(lambda x: x['c'].sample(frac=x['c'].iloc[0])).index, ['a','b']]
    Out[1]: 
       a  b
    6  7  0
    8  9  0
    3  4  1
    

    你说的20%和30%是什么意思?你是说你想从第0组中随机获得20%的项目,从第1组中随机获得30%的项目?您可以这样做,但由于您的组太小,因此对于此示例数据,每个组中只有一个项目。不确定有多少理由使用
    np。请选择
    。您可以只执行df.loc[db.b==0,'c']=0.3
    和其他组的类似操作。无需将分数转换为整数,因为
    sample
    接受一个可以取一定比例的
    frac
    参数。@BrenBarn
    np。选择
    是因为存在多个条件
    .loc
    是一种方式,但
    np。选择
    通常适用于多种情况。您必须在多行代码上编写
    .loc
    。这没什么错。这只是一种不同的方法。我喜欢你的
    。尽管如此,我还是喜欢你的
    组(0)
    代码。@BrenBarn Nvmd,我明白你现在使用
    frac
    的意思了。谢谢但是,如果指定一个
    frac
    >1,则这不起作用。我认为这也使得
    np.select
    .loc
    在我看来更干净一点。
    .reset\u index().rename({'index':'a'},axis=1)
    做什么@DavidErickson@user14862671这就是使用
    reset\u index()
    时发生的情况。尝试:
    。重命名({'level_1':'a'},axis=1))
    而不是
    。重命名({'index':'a'},axis=1))
    grouped = df.groupby('b', group_keys=False)
    df['c'] = np.select([df['b'].eq(0), df['b'].eq(1)], [0.4, 0.2])
    df.loc[grouped.apply(lambda x: x['c'].sample(frac=x['c'].iloc[0])).index, ['a','b']]
    Out[1]: 
       a  b
    6  7  0
    8  9  0
    3  4  1
    
    grouped = df.groupby('b', group_keys=False)
    v = df['b'].value_counts()
    df['c'] = np.select([df['b'].eq(0), df['b'].eq(1)],
                        [int(v.loc[0] * 1.2), int(v.loc[1] * 2)]) #frac parameter doesn't work with sample when frac > 1, so we have to calcualte the integer value for number of rows to be sampled.
    (grouped.apply(lambda x: x['b'].sample(x['c'].iloc[0], replace=True))
            .reset_index()
            .rename({'index' : 'a'}, axis=1))
    Out[2]: 
        a  b
    0   7  0
    1   8  0
    2   9  0
    3   7  0
    4   7  0
    5   8  0
    6   1  1
    7   3  1
    8   3  1
    9   1  1
    10  0  1
    11  0  1
    12  4  1
    13  2  1
    14  3  1
    15  0  1