Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/299.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python Numpy:基于上一个元素计算?_Python_Numpy - Fatal编程技术网

Python Numpy:基于上一个元素计算?

Python Numpy:基于上一个元素计算?,python,numpy,Python,Numpy,假设我有数组x和y: x = numpy.array([1,2,3,4,5,6,7,8,9,10]) # actual content is the a result of another calculation step 对于y,有一个公式,每个元素基于前面的元素,让i表示y的索引,每个元素是: y[i] = y[i-1] * 2 + x[i] 计算第一个元素时,让y[i-1]=50。换句话说,y应该是: [101, 204, 411, 826, 1657, 3320, 6647, 13

假设我有数组
x
y

x = numpy.array([1,2,3,4,5,6,7,8,9,10])  # actual content is the a result of another calculation step
对于
y
,有一个公式,每个元素基于前面的元素,让
i
表示
y
的索引,每个元素是:

y[i] = y[i-1] * 2 + x[i]
计算第一个元素时,让
y[i-1]=50
。换句话说,
y
应该是:

[101, 204, 411, 826, 1657, 3320, 6647, 13302, 26613, 53236]

如何使用numpy计算
y

x = [1, 2, 3, 4, 5, 6, 7, 8 ,9, 10]
y = [50]
for i in range(len(x)):
    y.append(y[-1] * 2 + x[i])
y = y[1:]

如果您需要递归计算,如果您的
y[i]
应该依赖于同一次运行中计算的
y[i-1]
,那么numpy中似乎没有内置的解决方案,那么您可能希望从最后一个元素开始计算它,以防止在下一次
i
中使用新值,您需要使用一个简单的
for
循环来计算它:

y = np.empty(x.size)
last = 50
for i in range(x.size):
    y[i] = last = last * 2 + x[i]
见这个问题:

否则,可以使用numpy在一行中实现公式:

y = np.concatenate(([50], y[:-1])) * 2 + x
说明:

y[:-1]
创建一个
N-1
大小的数组:
y\u 0,y\u 1。。。y\u N-1

np.concatenate(([50], y[:-1]))
创建一个
N
大小的数组,第一个元素的起始值为50。所以这个表达式基本上就是你的
y[i-1]


然后,您可以使用numpy数组算术进行数学元素分析。

让我们在序列中构建一些项:

y[0] = 2*y[-1] + x[0]
y[1] = 2*y[0] + x[1] = 4*y[-1] + 2*x[0] + x[1]
y[2] = 2*y[1] + x[2] = 8*y[-1] + 4*x[0] + 2*x[1] + x[2]
...
y[n] = 2**(n+1)*y[-1] + 2**n*x[0] + 2**(n-1)*x[1] + ... + x[n]
这可能不是很明显,但您可以使用numpy构建上述序列,例如:

n = len(x)
y_1 = 50
pot = 2**np.arange(n-1, -1, -1)
y = np.cumsum(pot * x) / pot + y_1 * 2**np.arange(1, n+1)
>>> y
array([  101,   204,   411,   826,  1657,  3320,  6647, 13302, 26613, 53236])

这种解决方案的缺点是它们不是很通用:问题中的一个小变化可能会使整个方法变得无用。但是,只要你能用一点代数来解决一个问题,它几乎肯定会远远超过任何算法方法。

这是如何用numpy来解决的:

import numpy as np
x = np.array([ 1, 2, 3, 4, 5, 6, 7, 8 ,9, 10 ])
y = np.array([ 50 ])
for i in np.arange(len(x)):
    y = np.append(
                  y,
                  ( y[-1] * 2 + x[i] )
                  )
y = y[1:]

print(y)

也许最快、最简洁的方法是使用,它完全实现了您描述的递归关系:

from scipy.signal import lfilter
import numpy as np

x = np.array([1,2,3,4,5,6,7,8,9,10])

b = [1., 0.]
a = [1., -2.]
zi = np.array([2*50])  # initial condition
y, _ = lfilter(b, a, x, zi=zi)
结果将是
np.float64
,但如果需要,您可以强制转换为例如
np.int32

>>> y.astype(np.int32)
array([  101,   204,   411,   826,  1657,  3320,  6647, 13302, 26613, 53236])

y
的起始值是多少,即
y[0]
?有一个人为的起始值50。你写的代码怎么了?@moose,这只是伪代码,不是numpy。这是一个非齐次线性递归方程。你有没有考虑过先找到解析解,然后看看它是否能被有效地编码?很好!然后更改
y
的第一个元素。输出不应该是
[101、204、411、826、1657、3320、6647、13302、26613、53236]
?和第二个元素不匹配?应该是204,而不是102这似乎不能正确处理复发。它看起来是为了从一个旧的
y
x
构建一个全新的
y
数组而设计的,而期望的行为似乎是将给定的关系保存在一个
y
数组中;期望的结果是这个解决方案的一个固定点。好吧,我想我当时误解了要求。如果OP想要一个递归公式,这个答案对他来说是行不通的。(当我写这个答案时,没有示例结果)实际上,我想要的是递归的,我没有意识到这一点,我希望numpy能够通过一些神奇的切片实现这一点。谢谢你的解释。我将继续使用for循环。我假设“如何使用numpy计算*”意味着一个有效的矢量化版本。@AmiTavory显然不是。我在评论中问过他的代码有什么问题,答案是“这是伪代码”。但我也认为费迪南德·拜尔斯的答案应该是被接受的答案(并获得了更高的票数),它甚至更简单,比如
y=[50*2+x[0];对于x[1:]:y.append(y[-1]*2+v)
而您的解决方案还不正确。嗯。。。我的意思是这是伪代码,要转换成numpy。我想我很清楚我想要一个numpy解决方案。然后你可以简单地将我这里的代码块复制到你的问题中,然后说你想要相同的结果,但是使用矢量化/高效的numpy解决方案。
numpy.cumsum()
比使用
for
循环快很多,对于我的测试应用程序快约8倍。