web-dev-qa-db-ja.com

Pandasの層別サンプリング

Sklearn stratified sampling docs および pandas docsPandasからの階層化サンプル および sklearn stratified列に基づいたサンプリング が、この問題に対処していません。

データセットからサイズnの成層サンプルを生成するための高速なpandas/sklearn/numpyの方法を探しています。ただし、指定されたサンプリング数より少ない行の場合は、すべてのエントリを取得する必要があります。

具体例:

enter image description here

ありがとうございました! :)

22
Wboy

番号をサンプルに渡すときに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
43
piRSquared

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_
4
Ilya Prokin

次のサンプルでは、​​各グループが最も近い整数に元の比率で表示される合計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)
))

短くて甘い:

df.sample(n=N, weights='A', random_state=1).reset_index(drop=True)

ロングバージョン

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)
1
irkinosor