方法#1
这是一个数组初始化 -
n = 4 # number of iterations to add outer versions
l = len(x)
out = np.zeros([l]*n,dtype=x.dtype)
for i in range(n):
out += x.reshape(np.insert([1]*(n-1),i,l))
为什么在每次迭代时使用这种方法而不是迭代添加来创建新数组?
在每次迭代中迭代地创建新数组将需要更多内存,因此需要更多内存开销。通过数组初始化,我们将x 的元素添加到已经初始化的数组中。因此,它尝试使用它来提高内存效率。
备选方案#1
我们可以通过使用x 进行初始化来删除一次迭代。因此,更改将是 -
out = np.broadcast_to(x,[l]*n).copy()
for i in range(n-1):
方法#2:使用np.add.reduce -
另一种方法是使用np.add.reduce,它也不会创建任何中间数组,但在这里作为一种归约方法可能会更好,因为它就是为此实现的 -
l = len(x); n = 4
np.add.reduce([x.reshape(np.insert([1]*(n-1),i,l)) for i in range(n)])
时间安排 -
In [17]: x = np.arange(100)
In [18]: %%timeit
...: n = 4 # number of iterations to add outer versions
...: l = len(x)
...: out = np.zeros([l]*n,dtype=x.dtype)
...: for i in range(n):
...: out += x.reshape(np.insert([1]*(n-1),i,l))
829 ms ± 28.1 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
In [19]: l = len(x); n = 4
In [20]: %timeit np.add.reduce([x.reshape(np.insert([1]*(n-1),i,l)) for i in range(n)])
183 ms ± 2.52 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)