我需要根据它们之前的元素同时填充两个相互依赖的数组,如下所示:
import numpy as np
a = np.zeros(100)
b = np.zeros(100)
c = np.random.random(100)
for num in range(1, len(a)):
a[num] = b[num-1] + c[num]
b[num] = b[num-1] + a[num]
有没有办法真正使用numpy对它进行矢量化(即不使用numpy.vectorize)?请注意,这些是任意数组,而不是寻找这些特定值的解决方案。
答案 0 :(得分:3)
正如@ Praveen的帖子中所提到的,我们可以编写那些表达式,用于尝试找到封闭形式的几次迭代,这当然是c
的三角矩阵。然后,我们只需添加迭代缩放 b[0]
即可获得完整b
。要获得a
,我们只需添加b
和c
的移位版本。
因此,为了提高效率,使用一些NumPy broadcasting
和dot-product
来实现这一点是不同的做法 -
p = 2**np.arange(a.size-1)
scale1 = p[:,None]//p
b_out = np.append(b[0],scale1.dot(c[1:]) + 2*p*b[0])
a_out = np.append(a[0],b_out[:-1] + c[1:])
如果a
和b
始终以0
开头,则最后两个步骤的代码将简化为 -
b_out = np.append(0,scale1.dot(c[1:]))
a_out = np.append(0,b_out[:-1] + c[1:])
答案 1 :(得分:2)
是的,有:
c = np.arange(100)
a = 2 ** c - 1
b = numpy.cumsum(a)
答案 2 :(得分:1)
显然,更新是:
a_i = b_i-1 + c_i
b_i = 2*b_i-1 + c_i
写出递归,
b_0 = c_0 # I'm not sure if c_0 is to be used
b_1 = 2*b_0 + c_1
= 2*c_0 + c_1
b_2 = 2*b_1 + c_2
= 2*(2*c_0 + c_1) + c_2
= 4*c_0 + 2*c_1 + c_2
b_3 = 2*b_2 + c_3
= 2*(4*c_0 + 2*c_1 + c_2) + c_3
= 8*c_0 + 4*c_1 + 2*c_2 + c_3
所以看起来似乎
b_i = np.sum((2**np.arange(i+1))[::-1] * c[:i])
a_i = b_i-1 + c_i
这里不可能累积总和,因为c_i
的系数不断变化。
完全矢量化的最简单方法是使用巨型矩阵。如果c
的尺寸为N
:
t = np.zeros((N, N))
x, y = np.tril_indices(N)
t[x, y] = 2 ** (x - y)
这给了我们:
>>> t
array([[ 1., 0., 0., 0.],
[ 2., 1., 0., 0.],
[ 4., 2., 1., 0.],
[ 8., 4., 2., 1.]])
现在你可以这样做:
b = np.sum(t * c, axis=1)
a = np.zeros(N)
a[1:] = b[:-1] + c[1:]
我可能不会推荐这个解决方案。从我对计算方法知之甚少,对于大N
而言,这似乎在数值上不稳定。但我感觉这对于任何最终执行求和的矢量化解决方案都是如此。也许你应该尝试使用for-loop和这段代码,看看你的错误是否继续引发矢量化解决方案。