【发布时间】:2021-03-08 18:10:46
【问题描述】:
我比较了在pandas/numpy/pure python 中添加两个向量需要多长时间,得到了一些令人惊讶的(对我来说)结果。
在 python3.6.9、Ubuntu 18.04、numpy=1.18.1、pandas==1.1.3 上测试。
代码
import pandas as pd
import numpy as np
import random
from timeit import timeit
repeat = 1000
max_exp =7
def time_all(a, b):
sa = pd.Series(a)
sb = pd.Series(b)
na = np.array(a)
nb = np.array(b)
py_sum = lambda: [x + y for x, y in zip(a, b)]
pd_sum = lambda: sa + sb
np_sum = lambda: na + nb
py_time = timeit(py_sum, number=repeat)
pd_time = timeit(pd_sum, number=repeat)
np_time = timeit(np_sum, number=repeat)
return py_time, pd_time, np_time
for i in range(2, max_exp):
size = 10 ** i
a = [random.randint(0, 100) for x in range(0, size)]
b = [random.randint(0, 100) for x in range(0, size)]
py_time, pd_time, np_time = time_all(a, b)
py_pd = round(py_time / pd_time, 4)
py_np = round(py_time / np_time, 4)
pd_np = round(pd_time / np_time, 4)
print('''
ARRAY SIZE: {}
PY/PD: {}
PY/NP: {}
PD/NP: {}'''.format(size, py_pd, py_np, pd_np))
结果
ARRAY SIZE: 100
PY/PD: 0.0357
PY/NP: 8.656
PD/NP: 242.1978
ARRAY SIZE: 1000
PY/PD: 0.3286
PY/NP: 44.3758
PD/NP: 135.05
ARRAY SIZE: 10000
PY/PD: 2.8774
PY/NP: 69.2828
PD/NP: 24.0785
ARRAY SIZE: 100000
PY/PD: 11.7784
PY/NP: 76.5296
PD/NP: 6.4974
ARRAY SIZE: 1000000
PY/PD: 26.2985
PY/NP: 33.1973
PD/NP: 1.2623
问题
- 对于小数组(最多约 5k 个元素),python 比 pandas 更有效,因为非常小,差异很大。有什么一般规则在纯 python 上的操作比 pandas 有(这么多)更好的性能吗?诸如“对于不到 100 行的熊猫,无论您做什么,都会慢一个数量级”?
- 据我了解,pandas 内部使用的是 numpy。这些性能是否仅因为 pd.Series 和 np.array 之间的转换时间而不同?如果是,有没有办法在创建系列时强制转换?
- (最不重要,但最令人惊讶)对于 10^6 数组,纯 python 比 numpy 慢约 77 倍,但对于 10^7,比率仅为 33。为什么?
【问题讨论】:
-
没什么太令人惊讶的。
numpy最快(从数组开始)。对于非常大的阵列,由于内存管理的复杂性,相对性能会下降。pandas使用 numpy 数组,但增加了跟踪行索引(可能更多)的开销。
标签: python pandas performance numpy