我在numpy Python中遇到了时间问题,我有一个小过程需要做很多次,而且计算起来太长了。
我有一个子程序,它为1D数组执行以下计算。
for i in range(len(my_array)):
new_array[i] = np.sum((my_array[i] + second_array)**(-1)*third_array)
由于第二和第三阵列的大小为O(1000(,因此该循环的每次迭代花费大约30微秒。我觉得这很好?问题是len(my_array) = 2**15
,因此迭代它需要非常长的时间(超过一秒钟(。对于我需要调用这个子程序的次数来说,这太慢了。有没有一种方法可以解决这个问题或其他问题,这样我就可以在一维上调用numpy.sum
并避免for循环,或者我如何优化它?如果这是我能做的最好的事情,我应该换成另一种语言吗?
编辑:
在hpaulj的建议下,我为矢量化计算编写了一个测试。
import numpy as np
import time
my_arr = np.linspace(0,10,2**15)
other_arr = np.empty([len(my_arr),2])
for i in range(2):
other_arr[:,i] = my_arr*2+5.3
sec_arr = np.linspace(-2,2,1000)
third_arr = np.exp(sec_arr+2)*3
t11 = time.time()
# + other_arr[:,0][:,None]
new_array = np.sum((my_arr[:,None] + sec_arr + other_arr[:,0][:,None])**(-1)*third_arr, axis = 1)
t12 = time.time()
vectortime = t12 - t11
new_array = np.empty(len(my_arr))
t21 = time.time()
for i in range(len(my_arr)):
new_array[i] = np.sum((my_arr[i]+ sec_arr + other_arr[i,0] )**(-1)*third_arr)
t22 = time.time()
looptime = (t22 - t21)
print(vectortime / looptime)
这似乎快了15%。如果额外的数组只有500个浮点长度,它的速度会快50%。当我在实际用例中尝试它时,my_array
实际上是dtype = 'complex128'
,但我没有看到时间增加。my_array
与1j
的乘积也消除了速度的增加。有解决办法吗?
我将其与一位同事的FORTRAN代码进行比较,后者的运行速度快250%。我可以期望与编译语言的竞争有多激烈?
由于您还没有提供一个最小的示例,所以我将在不测试的情况下抛出一个建议。
new_array[i] = np.sum((my_array[i] + second_array)**(-1)*third_array)
将循环重写为
new_array = np.sum((my_array[:,None] + second_array)**(-1)*third_array, axis=1)
如果my_array
是(N,(而其他是(M,(,
(N,1)+(M,) => (N,M)
(N,M)+(M,) => (N,M)
sum(N,M) => (N,)