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

此函数按单列分组并返回每个组的目标达到其最大值的所有行;返回结果数据框。

如果 df 有 500K 行,上述函数在我的计算机上大约需要 5 分钟才能完成。这个性能还可以,但是我有超过 1000 万行的数据......当然,一种解决方案是在 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

请注意,这与组数成正比,但系数非常小。例如。我做 100x 组,速度只有 2x。Transform 在广播时非常有效。

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 回答