Numpy:根据之前的元素计算?

He *_*ing 8 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
Run Code Online (Sandbox Code Playgroud)

有一个公式y,并且每个元素都基于前一个元素,让我们i表示索引y,每个元素是:

y[i] = y[i-1] * 2 + x[i]
Run Code Online (Sandbox Code Playgroud)

在计算第一个元素时,让y[i-1] = 50.换句话说,y应该是:

[101, 204, 411, 826, 1657, 3320, 6647, 13302, 26613, 53236]
Run Code Online (Sandbox Code Playgroud)

我怎么y用numpy 计算?

Jai*_*ime 6

让我们按顺序构建一些项目:

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]
Run Code Online (Sandbox Code Playgroud)

这可能不是立即显而易见的,但是您可以使用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])
Run Code Online (Sandbox Code Playgroud)

这种类型的解决方案的不利之处在于它们不是很通用:您的问题的微小变化可能会使整个方法变得无用。但是只要您能用一点代数解决问题,几乎可以肯定的是,它将远远击败任何算法方法。


Fer*_*yer 5

如果您需要递归计算,那么您y[i]应该依赖于y[i-1]同一运行中的计算,那么numpy中似乎没有内置解决方案,您将需要使用一个简单的for循环来进行计算:

y = np.empty(x.size)
last = 50
for i in range(x.size):
    y[i] = last = last * 2 + x[i]
Run Code Online (Sandbox Code Playgroud)

看到这个问题:如果numpy向量的元素依赖于前一个元素,是否需要“ for”循环?

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

y = np.concatenate(([50], y[:-1])) * 2 + x
Run Code Online (Sandbox Code Playgroud)

说明:

y[:-1]
Run Code Online (Sandbox Code Playgroud)

创建一个N-1大小数组:y_0, y_1, ... y_N-1

np.concatenate(([50], y[:-1]))
Run Code Online (Sandbox Code Playgroud)

创建一个N大小为第一个元素的数组,其第一个元素的起始值为50。因此,该表达式基本上是您的y[i-1]

然后,您可以使用numpy数组算法对数学元素进行算术运算。

  • 这似乎无法正确处理复发。看起来它是从旧的y和x构造一个全新的y数组,而所需的行为似乎是将给定的关系保留在单个y数组中;期望的结果将是该解决方案的一个固定点。 (2认同)