2014-09-25 82 views
1

更新numpy的陣列順序我有一個numpy的陣列v,我想用數組的當前元素上的功能更新每個元素:如何在沒有環路

v[i] = f(v, i) 

一個基本的方式做這是使用一個循環

for i in xrange(2, len(v)): 
    v[i] = f(v, i) 

因此用於更新訴值[I]是更新陣列v。有沒有辦法做這些更新沒有循環?

例如,

v = [f(v, i) for i in xrange(len(v))] 

由於V不工作[I-1]當在綜合列表用於不被更新。

i將函數˚F可以取決於在列表上的幾個元素,那些具有索引低於我應該更新和那些與比我尚未更新索引時,如下面的例子:

v = [1, 2, 3, 4, 5] 
f = lambda v, i: (v[i-1] + v[i])/v[i+1] # for i = [1,3] 
f = lambda v, i: v[i]      # for i = {0,4} 

它應該返回

v = [1, (1+2)/3, (1+4)/4, ((5/4)+4)/5, 5] 

回答

1

你可以使用和sum功能v[i]之前的數字:

>>> v = [v[i] + sum(v[:i]) for i in xrange(len(v))] 
>>> v 
[1, 3, 6, 10, 15] 

或以更好的方式,你可以使用np.cumsum()

>>> np.cumsum(v) 
array([ 1, 3, 6, 10, 15]) 
+0

考慮numpy的在大型陣列使用,O(N²)算法,實際上會比一個純Python循環更差,這甚至沒有矢量化。 – Veedrac 2014-09-25 18:09:23

2

有這個功能:

import numpy 

v = numpy.array([1, 2, 3, 4, 5]) 

numpy.add.accumulate(v) 
#>>> array([ 1, 3, 6, 10, 15]) 

這適用於許多不同類型的ufunc

numpy.multiply.accumulate(v) 
#>>> array([ 1, 2, 6, 24, 120]) 

對於這種類型的任意函數o ˚F積累,你可以讓自己的ufunc,雖然這將是很慢:

myfunc = numpy.frompyfunc(lambda x, y: x + y, 2, 1) 
myfunc.accumulate([1, 2, 3], dtype=object) 
#>>> array([1, 3, 6], dtype=object) 
+0

如果僅使用索引i-1更新索引i處的v,則此方法運行良好。但它不適用於像f(v [i])= v [i-1] + v [i] + v [i + 1]這樣的函數,因爲累加只需要帶兩個參數的函數。 – haaronn 2014-09-29 15:40:03

+0

我編輯了我的問題來添加f有三個參數的情況。 – haaronn 2014-09-29 15:49:10

+0

@haron你應該問一個新的問題。 – Veedrac 2014-09-29 16:02:03