gpt4 book ai didi

python - Numpy 数组索引和/或添加似乎很慢

转载 作者:行者123 更新时间:2023-11-28 20:45:50 26 4
gpt4 key购买 nike

我一直在尝试对 numpy 数组进行基准测试,因为当我尝试在脚本中用 numpy 数组替换 python 数组时,结果比预期的要慢。

我知道我遗漏了一些东西,我希望有人能消除我的无知。

我创建了两个函数并为它们计时

NUM_ITERATIONS = 1000

def np_array_addition():
np_array = np.array([1, 2])
for x in xrange(NUM_ITERATIONS):
np_array[0] += x
np_array[1] += x


def py_array_addition():
py_array = [1, 2]
for x in xrange(NUM_ITERATIONS):
py_array[0] += x
py_array[1] += x

结果:

np_array_addition: 2.556 seconds
py_array_addition: 0.204 seconds

什么给了?是什么导致了大规模放缓?我想,如果我使用静态大小的数组,numpy 至少会有相同的速度。

谢谢!

更新:

numpy 数组访问速度缓慢一直困扰着我,我想“嘿,它们只是内存中的数组,对吧?Cython 应该可以解决这个问题!”

确实如此。这是我修改后的基准

import numpy as np
cimport numpy as np

ctypedef np.int_t DTYPE_t


NUM_ITERATIONS = 200000
def np_array_assignment():
cdef np.ndarray[DTYPE_t, ndim=1] np_array = np.array([1, 2])
for x in xrange(NUM_ITERATIONS):
np_array[0] += 1
np_array[1] += 1


def py_array_assignment():
py_array = [1, 2]
for x in xrange(NUM_ITERATIONS):
py_array[0] += 1
py_array[1] += 1

我将 np_array 重新定义为 cdef np.ndarray[DTYPE_t, ndim=1]

print(timeit(py_array_assignment, number=3))
# 0.03459
print(timeit(np_array_assignment, number=3))
# 0.00755

那是 python 函数也被 cython 优化了。纯python中python函数的时机是

print(timeit(py_array_assignment, number=3))
# 0.12510

17 倍的加速。当然,这是一个愚蠢的例子,但我认为它具有教育意义。

最佳答案

这不是(只是)缓慢的加法,而是元素访问开销,例如:

def np_array_assignment():
np_array = np.array([1, 2])
for x in xrange(NUM_ITERATIONS):
np_array[0] = 1
np_array[1] = 1


def py_array_assignment():
py_array = [1, 2]
for x in xrange(NUM_ITERATIONS):
py_array[0] = 1
py_array[1] = 1

timeit np_array_assignment()
10000 loops, best of 3: 178 us per loop

timeit py_array_assignment()
10000 loops, best of 3: 72.5 us per loop

当一次对整个结构执行操作时,Numpy 对向量(矩阵)的操作速度很快。这种逐个元素的操作很慢。

使用 numpy 函数来避免循环,一次对整个数组进行操作,即:

def np_array_addition_good():
np_array = np.array([1, 2])
np_array += np.sum(np.arange(NUM_ITERATIONS))

将你的函数与上面的函数进行比较的结果非常有启发性:

timeit np_array_addition()
1000 loops, best of 3: 1.32 ms per loop

timeit py_array_addition()
10000 loops, best of 3: 101 us per loop

timeit np_array_addition_good()
100000 loops, best of 3: 11 us per loop

但实际上,如果你折叠循环,你可以用纯 python 做同样的事情:

def py_array_addition_good():
py_array = [1, 2]
rangesum = sum(range(NUM_ITERATIONS))
py_array = [x + rangesum for x in py_array]

timeit py_array_addition_good()
100000 loops, best of 3: 11 us per loop

总而言之,就这么简单的操作,使用numpy确实没有任何提升。纯 Python 中的优化代码同样有效。


有很多关于它的问题,我建议看看那里的一些好的答案:

How do I maximize efficiency with numpy arrays?

numpy float: 10x slower than builtin in arithmetic operations?

关于python - Numpy 数组索引和/或添加似乎很慢,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22239199/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com