【发布时间】:2014-03-06 19:25:06
【问题描述】:
我需要一些分箱数据的统计信息。
我认为pandas groupby 方法将是一种非常自然的方法。
为了提高性能,我意识到从传递给agg 的列表中删除count 方法会显着提高。
令我惊讶的是,从总和/平均值的比率中提取计数会带来显着的改进。 在我的实际应用中,这导致计算时间缩短了 100 倍。
我想知道我是否以某种方式滥用了代码。
在下面你可以找到一个人工的例子:
In [1]: import numpy as np
In [2]: import pandas as pd
In [3]: df = pd.DataFrame({'x':np.random.randn(5000), ## produce the demo DataFrame
...: 'y':np.random.randn(5000),
...: 'z':np.random.randn(5000)})
In [4]: buckets = {col : np.arange(int(df[col].min()) ,int(df[col].max())+2)
...: for col in df.columns} ## produce the unit bins
In [5]: cats = [pd.cut(df[col], bucket) for col,bucket in buckets.iteritems()]
In [6]: grouped = df.groupby(cats) # group by the binned x,y,z
In [7]: %%timeit
...: fast_count = grouped.x.agg(['sum','mean','var'])
...: fast_count = (fast_count['sum']/fast_count['mean'] + 0.5).astype(np.int) ...:
1000 loops, best of 3: 1.06 ms per loop
In [8]: %%timeit
...: slow_count = grouped.x.count()
...:
100 loops, best of 3: 18.9 ms per loop
In [9]: fast_count = grouped.x.agg(['sum','mean','var'])
In [10]: fast_count = (fast_count['sum']/fast_count['mean'] + 0.5).astype(np.int)
In [11]: slow_count = grouped.x.count()
In [12]: (fast_count != slow_count).sum()
Out[12]: 0
In [13]: (fast_count == slow_count).sum()
Out[13]: 204
感谢 Jeff 的回复(下),更优雅的代码(显示可比性能):
In [17]: %%timeit
....: another_fast_count = grouped.x.size()
....:
1000 loops, best of 3: 609 µs per loop
请参阅 Jeff 回复后的 cmets 以获得一些解释
NB(基于hayd's comment):
count 只计算非空元素,而size 不会区分。
这可能是性能差异的原因。
因此,应谨慎选择这两个选项。
【问题讨论】:
标签: python count group-by pandas