传播计算结果

时间:2018-08-21 01:00:00

标签: python numpy

我想初始化一个与此类似的数组b,但要更快:

a = [0.53, 0.66, 0.064, 0.94, 0.44]
b = [0.0]*5
x = 14.3
for i in range(5):
    x = b[i] = a[i]*0.1 + x*0.9

出于这个目的,在numpy中有东西吗?

3 个答案:

答案 0 :(得分:4)

一个丑陋但矢量化的numpy解决方案:

import numpy as np
a = np.array([0.53, 0.66, 0.064, 0.94, 0.44])
x = 14.3
idx = np.arange(a.size)
0.9 ** idx * (0.1 * (a * 0.9 ** (-idx)).cumsum() + x * 0.9)
# array([12.923    , 11.6967   , 10.53343  ,  9.574087 ,  8.6606783])

for循环的结果:

a = [0.53, 0.66, 0.064, 0.94, 0.44]
b = [0.0]*5
x = 14.3
for i in range(5):
    x = b[i] = a[i]*0.1 + x*0.9

b
#[12.923000000000002,
# 11.696700000000003,
# 10.533430000000003,
# 9.574087000000002,
# 8.660678300000002]

这是因为:

enter image description here

并且结果中的分量可以相应地矢量化,请注意,括号内的a项之和矢量化为cumsum

答案 1 :(得分:3)

也许我们可以分解并找到每个步骤之间的相关性

***x0=x0***

***x1=a[0]*0.1 + x0*0.9***

***x2=a[1]*0.1 + x1*0.9=a[1]*0.1 + (a[0]*0.1 + x0*0.9)*0.9***

所以 xn=an*0.1+an-1*0.1*0.9+...+a0*0.1*0.9**n-1+x0*0.9**n

n=np.array(0.9)**np.arange(len(a))


sum(a[::-1]*n)*0.1+x*(0.9**(len(a)))
Out[338]: 8.6606783

更新输出array

np.diag(np.fliplr(((a*n[::-1])*0.1).cumsum()/n[:,None]+x*(0.9**(np.arange(1,len(a)+1)))))[::-1]
Out[472]: array([12.923    , 11.6967   , 10.53343  ,  9.574087 ,  8.6606783])

答案 2 :(得分:2)

让我们重写您的循环以更仔细地分析它:

for i in range(1, 5):
    b[i] = a[i]*0.1 + b[i-1]*0.9

这清楚表明计算是递归的。即,b[i]的值取决于b[i-1]的值。这意味着您无法向量化计算。向量化要求结果向量的每个元素都独立于所有其他元素。