Wenn Sie brauchen etwas schnell, np.bincount
könnte eine gute Lösung inst sein ead eines Pandas groupby.
np.bincount(df.loc[df.b > 20, 'a'])/np.bincount(df.a))
die
array([ 1. , 0.33333333, 0.5 ])
zurück Oder wenn Sie die Ausgabe zurück auf eine Reihe verwandeln wollte, Sie anschließend np.take
nutzen könnten.
pd.Series((np.bincount(df.loc[df.b > 20, 'a'])/np.bincount(df.a)).take(df.a))
# 0 1.000000
# 1 1.000000
# 2 0.333333
# 3 0.333333
# 4 0.333333
# 5 0.500000
# 6 0.500000
# dtype: float64
In jedem Fall scheint dies ziemlich schnell zu sein.
Kleinere Fall: bereitgestellt Dataset
groupby
Ansatz aus MAXU
%timeit df.groupby('a')['b'].transform(lambda x: x.gt(20).mean())
2.51 ms ± 65.2 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
np.bincount
Ansatz
%timeit pd.Series((np.bincount(df.loc[df.b > 20, 'a'])/np.bincount(df.a)).take(df.a))
271 µs ± 5.28 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
Larg er Fall: erzeugte Datenmenge
df = pd.DataFrame({'a': np.random.randint(0, 10, 100000),
'b': np.random.randint(0, 100, 100000)}).sort_values('a')
groupby
Ansatz aus MAXU
%timeit df.groupby('a')['b'].transform(lambda x: x.gt(20).mean())
11.3 ms ± 40.2 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
np.bincount
Ansatz
%timeit pd.Series((np.bincount(df.loc[df.b > 20, 'a'])/np.bincount(df.a)).take(df.a))
1.56 ms ± 5.47 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
Warum Sie verwenden bedeuten statt sum/len? – Elham
@AlterNative, es gibt uns das gleiche Ergebnis, aber es ist schöner, kürzer und erfordert weniger Operationen ... PS eigentlich 'mean (lst) == sum (lst)/len (lst)' ;-) – MaxU