我发现简单系列操作中pandas 0.11和pandas 0.13之间的性能差异很大。
In [7]: df = pandas.DataFrame({'a':np.arange(1000000), 'b':np.arange(1000000)})
In [8]: pandas.__version__
Out[8]: '0.13.0'
In [9]: %timeit df['a'].values+df['b'].values
100 loops, best of 3: 4.33 ms per loop
In [10]: %timeit df['a']+df['b']
10 loops, best of 3: 42.5 ms per loop
在版本0.11上(在同一台机器上),
In [10]: pandas.__version__
Out[10]: '0.11.0'
In [11]: df = pandas.DataFrame({'a':np.arange(1000000), 'b':np.arange(1000000)})
In [12]: %timeit df['a'].values+df['b'].valuese
100 loops, best of 3: 2.22 ms per loop
In [13]: %timeit df['a']+df['b']
100 loops, best of 3: 2.3 ms per loop
所以在0.13上,它的速度要慢20倍。剖析它,我看到了
ncalls tottime percall cumtime percall filename:lineno(function)
1 0.000 0.000 0.047 0.047 <string>:1(<module>)
1 0.000 0.000 0.047 0.047 ops.py:462(wrapper)
3 0.000 0.000 0.044 0.015 series.py:134(__init__)
1 0.000 0.000 0.044 0.044 series.py:2394(_sanitize_array)
1 0.000 0.000 0.044 0.044 series.py:2407(_try_cast)
1 0.000 0.000 0.044 0.044 common.py:1708(_possibly_cast_to_datetime)
1 0.044 0.044 0.044 0.044 {pandas.lib.infer_dtype}
1 0.000 0.000 0.003 0.003 ops.py:442(na_op)
1 0.000 0.000 0.003 0.003 expressions.py:193(evaluate)
1 0.000 0.000 0.003 0.003 expressions.py:93(_evaluate_numexpr)
所以它花了很多时间在_possibly_cash_to_datetime和pandas.lib.infer_dtype上。
预计会有这种变化吗?如何才能恢复旧的,更快的性能?
注意:问题是输出是整数类型。如果我把其中一个列加倍,那就会变得很快......
答案 0 :(得分:2)
这是一个非常奇怪的错误(我想),在cython中进行奇怪的查找。出于某种原因
_TYPE_MAP = { np.int64 : 'integer' }
np.int64 in _TYPE_MAP
没有正确评估,仅适用于int64
(但对所有其他dtypes工作得很好)。由于某些原因,np.dtype
对象的哈希值可能很复杂。在任何情况下,修复此处:https:github.com/pydata/pandas/pull/7342所以我们使用名称哈希代替。
这里是性能比较:
主
In [1]: df = pandas.DataFrame({'a':np.arange(1000000), 'b':np.arange(1000000)})
In [2]: %timeit df['a'] + df['b']
100 loops, best of 3: 2.49 ms per loop
0.14.0
In [6]: df = pandas.DataFrame({'a':np.arange(1000000), 'b':np.arange(1000000)})
In [7]: %timeit df['a'] + df['b']
10 loops, best of 3: 35.1 ms per loop