Pandas 加速应用于 max()
Pandas speedup apply on max()
我想知道如何加快以下功能,例如使用 Cython?
def groupby_maxtarget(df, group, target):
df_grouped = df.groupby([group]).apply(lambda row: row[row[target]==row[target].max()])
return df_grouped
此函数按单个列和 returns 所有行分组,其中每个组的目标达到其最大值;返回结果数据帧。
如果 df 有 500K 行,上述函数在我的计算机上大约需要 5 分钟才能完成。这种性能还可以,但是我有超过 1000 万行的数据......当然,一种解决方案是在 SQL 服务器中将上述内容作为查询执行,并让 Python 检索结果,但我希望有一个 SQL 免费的 Pythonic 解决方案。
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
我想知道如何加快以下功能,例如使用 Cython?
def groupby_maxtarget(df, group, target):
df_grouped = df.groupby([group]).apply(lambda row: row[row[target]==row[target].max()])
return df_grouped
此函数按单个列和 returns 所有行分组,其中每个组的目标达到其最大值;返回结果数据帧。
如果 df 有 500K 行,上述函数在我的计算机上大约需要 5 分钟才能完成。这种性能还可以,但是我有超过 1000 万行的数据......当然,一种解决方案是在 SQL 服务器中将上述内容作为查询执行,并让 Python 检索结果,但我希望有一个 SQL 免费的 Pythonic 解决方案。
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