大熊猫的分层抽样

Wbo*_*boy 25 python numpy pandas scikit-learn

我已经查看了Sklearn分层抽样文档以及大熊猫文档以及来自Pandas的分层样本基于列的sklearn分层抽样,但他们没有解决这个问题.

我正在寻找一种快速的pandas/sklearn/numpy方法,从数据集中生成大小为n的分层样本.但是,对于小于指定采样数的行,它应该采用所有条目.

具体例子:

在此输入图像描述

谢谢!:)

piR*_*red 47

使用min合格样品数时.考虑数据帧df

df = pd.DataFrame(dict(
        A=[1, 1, 1, 2, 2, 2, 2, 3, 4, 4],
        B=range(10)
    ))

df.groupby('A', group_keys=False).apply(lambda x: x.sample(min(len(x), 2)))

   A  B
1  1  1
2  1  2
3  2  3
6  2  6
7  3  7
9  4  9
8  4  8
Run Code Online (Sandbox Code Playgroud)

  • @piRSquared,假设我有一个有 1M 行的 df,我想对其中的 10k 进行采样,每个 user_id 至少有 10 个样本,您将如何处理它? (4认同)

Ily*_*kin 11

扩展groupby答案,我们可以确保样本是平衡的。为此,当所有类别的样本数为 >= 时n_samples,我们可以n_samples针对所有类别(先前的答案)。当少数类包含 < 时n_samples,我们可以取所有类的样本数与少数类相同。

def stratified_sample_df(df, col, n_samples):
    n = min(n_samples, df[col].value_counts().min())
    df_ = df.groupby(col).apply(lambda x: x.sample(n))
    df_.index = df_.index.droplevel(0)
    return df_
Run Code Online (Sandbox Code Playgroud)

  • 解释,发布的代码做什么以及如何解决问题中的问题,很少不能改善答案。 (4认同)

irk*_*sor 5

以下示例总共 N 行,其中每个组以其与最接近的整数的原始比例出现,然后使用以下方法混洗和重置索引:

df = pd.DataFrame(dict(
    A=[1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 3, 3, 4, 4, 4, 4, 4],
    B=range(20)
))
Run Code Online (Sandbox Code Playgroud)

简短而甜蜜:

df.sample(n=N, weights='A', random_state=1).reset_index(drop=True)
Run Code Online (Sandbox Code Playgroud)

长版

df.groupby('A', group_keys=False).apply(lambda x: x.sample(int(np.rint(N*len(x)/len(df))))).sample(frac=1).reset_index(drop=True)
Run Code Online (Sandbox Code Playgroud)

  • 简短版本存在一个问题,它没有保留原始比例:使用参数权重=类别列并没有真正意义,例如它可以是字符串。如果您确实想使用 df.sample,则需要计算等于类别列频率的附加列。但长版本有效! (5认同)