2017-02-23 62 views
1

我一直無法在其他地方找到答案。1D Numpy陣列相當於先前,當前和以下元素的壓縮

對於一維numpy的隨機數組,例如a = np.random.rand(10),我想對每個包含它的每個相鄰元素(即前一個和後一個元素)的元素執行一個操作。所以,像

write = [] 

for previous_item, current_item, next_item in zip(a,a[1::],a[2::]): 
    write += operation_on(previous_item, current_item, next_item) 

但是當我嘗試用numpy的陣列上的那些片商要做到這一點,它告訴我,a[1::]等是浮動。是否有一個Numpy-Array等效於壓縮數組中的相鄰元素?

這裏是什麼,我不能去上班一個簡單的版本:

from random import randint 
import math 
import numpy as np 

size = 3 

def logistic(x,b): 
    return b*x*(1-x) 

def scheme(l,c,r,strength,b): 
    print('neighborhood: ',l,c,r) 
    new_center = (1-strength)*logistic(c,b)+(strength/2)*(logistic(r,b) + logistic(l,b)) 
    return new_center 

def eSimple(c,l=None,r=None): 
    return c 

cml = np.random.rand(size**2) 

def evolve(cml, r): 
    # encode all 
    cml = np.vectorize(eSimple)(cml[:-2], cml[1:-1], cml[2:]) 
    cml = np.vectorize(scheme)(cml[:-2], cml[1:-1], cml[2:], 0.5, r) 

for r in np.arange(3.6, 4.0, 0.05): 
    evolve(cml,r) 
    print(cml) 

出於某種原因,儘管它正確生成的街區,cml僅僅是增加其值由一個非常小的(〜1E-6 )從每個步驟的初始隨機值開始計算。

我錯過了什麼?

+0

若本只適用於一維numpy數組? –

+0

我試過你的代碼,如果我爲operation_on插入一些東西,它對我有用,雖然結果有點無聊(寫入被強制爲一個空數組,並且將一個標量添加到一個空數組並沒有多大作用) –

+0

@ sphericalcowboy I don真的不介意 - 我只想要一種方法來做到這一點。我想使用一維Numpy數組,而不是一個列表,但就目前而言,我只能找出一種方法來完成列表。 –

回答

0

這樣做的numpy方式將是

write = operation_on(a[:-2], a[1:-1], a[2:]) 

但這隻適用於如果operation_on矢量化。例如,如果operation_on(x, y, z)返回x*x - np.sin(y) + np.exp(z)它將工作,因爲單個操作都知道如何處理數組。

如果不是,您可以使用

write = np.vectorize(operation_on)(a[:-2], a[1:-1], a[2:]) 

注意,這將讓你的方便,但numpy的不是速度。

+0

當我以這種方式運行時,即使函數I返回'r * x *(1-x)',而'r'是另一個參數,這些值似乎會增加一個令人難以置信的小數量,所以它似乎符合你的矢量化要求 –

+0

@JackLynch我認爲你的函數需要3個參數? –

+0

我的不好 - 我的功能需要這三個,並且將中心元素應用於其他兩個的「地圖」(這就是我所描述的)。在這裏,我只是編輯我的答案,在不知道你的'.encode'方法的情況下發布我的代碼 –

0

首先,您可能希望三個數組的長度相同。這意味着要麼填充所述陣列的端部,或遍歷8個元素,而不是10。這裏是後一種方法:

for p, c, n in zip(a[:-2], a[1:-1], a[2:]): 
    ... 

此語法將相同方式工作爲一個列表或陣列。主要區別在於列表切片將返回副本,而數組切片是對同一底層緩衝區的視圖。

如果你堅持使用for循環爲你處理而不是向量化的功能,您可以消除拉鍊完全和使用一個二維數組得到邊際改善:

b = np.stack((a[:-2], a[1:-1], a[2:]), -1) 
for p, c, n in b: 
    ... 
+0

如果我沒有完全弄錯,zip會將它的參數截斷爲最短的長度。 –

+0

@PaulPanzer。真正。我正在努力從這個混亂中獲得一個2D數組,但意識到它沒有幫助。 –

+0

此外,即使其他形式的作品,我認爲你的風格更好。顯式比隱式更好。 –

0

如果你開始元素1與元素-2結束,即只使用兩個鄰國(前一個和下一個元素)元素:

import numpy as np 


def operation(pre, cur, nex): 
    return pre + cur + nex # sum as an example operation 


a = np.random.randint(3, size=(10,)) # output easier to see using ints 
write = [] 

for pr, cr, nx in zip(a[:-2], a[1:-1], a[2:]): 
    write.append(operation(pr, cr, nx)) 

print(a) 
print(write) 

輸出:

[0 2 2 0 0 1 0 1 1 1] 
[4, 4, 2, 1, 1, 2, 2, 3]