升级后Pandas系列操作非常慢
我发现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时,花费了大量时间。
这个变化是预期中的吗?我该如何恢复到以前更快的性能呢?
注意:看起来问题出在输出的数据类型是整数。如果我把其中一列改成双精度类型,它又变得快了……
1 个回答
2
这个问题很奇怪,可能和cython中的某种查找有关。出于某种原因,
_TYPE_MAP = { np.int64 : 'integer' }
np.int64 in _TYPE_MAP
在处理int64
时没有正确计算,但对于其他所有数据类型都能正常工作。可能是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