1

Cython などを使用して、次の関数を高速化する方法を知りたいですか?

def groupby_maxtarget(df, group, target):
    df_grouped = df.groupby([group]).apply(lambda row: row[row[target]==row[target].max()])
    return df_grouped

この関数は、1 つの列でグループ化し、各グループのターゲットが最大値を達成するすべての行を返します。結果のデータフレームが返されます。

df にたとえば 500K 行がある場合、上記の関数は私のコンピューターで完了するのに約 5 分かかります。このパフォーマンスは問題ありませんが、1,000 万行を超えるデータがあります... もちろん、1 つの解決策は、SQL サーバー内でクエリとして上記を実行し、Python に結果を取得させることですが、SQL-無料の Pythonic ソリューション。

4

1 に答える 1

4
In [22]: pd.set_option('max_rows',20)

In [33]: N = 10000000

In [34]: df = DataFrame({'A' : np.random.randint(0,100,size=N), 'B' : np.random.randint(0,100,size=N)})

In [35]: df[df.groupby('A')['B'].transform('max') == df['B']]
Out[35]: 
          A   B
161      30  99
178      53  99
264      58  99
337      96  99
411      44  99
428      85  99
500      84  99
598      98  99
602      24  99
684      31  99
...      ..  ..
9999412  25  99
9999482  35  99
9999502   6  99
9999537  24  99
9999579  65  99
9999680  32  99
9999713  74  99
9999886  90  99
9999887  57  99
9999991  45  99

[100039 rows x 2 columns]

In [36]: %timeit df[df.groupby('A')['B'].transform('max') == df['B']]
1 loops, best of 3: 1.85 s per loop

これはグループ数に比例しますが、係数はかなり小さいことに注意してください。例えば。私は 100 倍のグループを実行し、速度は 2 倍しかありません。トランスフォームはブロードキャストするので非常に効率的です。

In [8]: G = 100

In [9]: df = DataFrame({'A' : np.random.randint(0,G,size=N), 'B' : np.random.randint(0,G,size=N)})

In [10]: %timeit df[df.groupby('A')['B'].transform('max') == df['B']]
1 loops, best of 3: 1.86 s per loop

In [11]: G = 10000

In [12]: df = DataFrame({'A' : np.random.randint(0,G,size=N), 'B' : np.random.randint(0,G,size=N)})

In [13]: %timeit df[df.groupby('A')['B'].transform('max') == df['B']]
1 loops, best of 3: 3.95 s per loop
于 2015-02-17T00:40:24.410 に答える