【问题标题】:Optimizing method for numpy sum of arrays数组numpy总和的优化方法
【发布时间】:2021-09-24 11:33:37
【问题描述】:

我在 numpy Python 中遇到了计时问题,我有一个小程序需要执行很多次,而且计算时间过长。

我有一个对一维数组进行以下计算的子程序。

    for i in range(len(my_array)):
        new_array[i] = np.sum((my_array[i] + second_array)**(-1)*third_array)

此循环的每次迭代大约需要 30 微秒,因为第二个和第三个数组的大小为 O(1000)。我觉得这样好吗?问题是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%。我可以与编译语言竞争多远?

【问题讨论】:

  • 你的数组是什么形状的?
  • @RandomGuy 抱歉,它们都是一维数组

标签: numpy for-loop optimization sum numpy-ndarray


【解决方案1】:

由于你没有提供一个最小的例子,所以我只是抛出一个建议而不测试它。

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,)

【讨论】:

  • 我将其称为矢量化版本是否正确?我认为这是我在 Python 中能做的最好的事情,但我想知道如果其中一些是复杂数组,你是否碰巧有技巧?
猜你喜欢
  • 2019-04-21
  • 1970-01-01
  • 2012-07-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-06-28
  • 1970-01-01
  • 2021-12-20
相关资源
最近更新 更多