web-dev-qa-db-ja.com

pandas groupbyの後の各グループをサンプル

私はこれがどこかで答えられたに違いないことを知っていますが、私はそれを見つけることができませんでした。

問題:groupby操作後に各グループをサンプリングします。

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

# now sample from each group, e.g., I want 30% of each group
23
gongzhitaao

ラムダを適用し、パラメータsamplefrac を呼び出します。

In [2]:
df = pd.DataFrame({'a': [1,2,3,4,5,6,7],
                   'b': [1,1,1,0,0,0,0]})
​
grouped = df.groupby('b')
grouped.apply(lambda x: x.sample(frac=0.3))

Out[2]:
     a  b
b        
0 6  7  0
1 2  3  1
43
EdChum

各グループの一部をサンプリングする

_GroupBy.apply_sample と組み合わせて使用​​できます。ラムダを使用する必要はありません。 applyはキーワード引数を受け入れます:

_frac = .3
df.groupby('b').apply(pd.DataFrame.sample, frac=.3)
     a  b
b        
0 6  7  0
1 0  1  1
_

MultiIndexが不要な場合は、groupbyに_group_keys=False_を指定できます。

_df.groupby('b', group_keys=False).apply(pd.DataFrame.sample, frac=.3)

   a  b
6  7  0
2  3  1
_

各グループのN行のサンプル

applyは遅いです。ユースケースが固定数の行をサンプリングする場合、事前にDataFrameをシャッフルしてから、 _GroupBy.head_ を使用できます。

_df.sample(frac=1).groupby('b').head(2)

   a  b
2  3  1
5  6  0
1  2  1
4  5  0
_

これはdf.groupby('b', group_keys=False).apply(pd.DataFrame.sample, n=N)と同じですが、が高速ですが

_%%timeit df.groupby('b', group_keys=False).apply(pd.DataFrame.sample, n=2)  
                                                 # 3.19 ms ± 90.5 µs
%timeit df.sample(frac=1).groupby('b').head(2)   # 1.56 ms ± 103 µs
_
5
cs95