2013-04-18 104 views
3

我寫了一個小腳本,通過了解他們的行和列值分配到numpy的陣列列分配座標:行,沒有for循環

gridarray = np.zeros([3,3]) 
gridarray_counts = np.zeros([3,3]) 

cols = np.random.random_integers(0,2,15) 
rows = np.random.random_integers(0,2,15) 
data = np.random.random_integers(0,9,15) 

for nn in np.arange(len(data)): 
    gridarray[rows[nn],cols[nn]] += data[nn] 
    gridarray_counts[rows[nn],cols[nn]] += 1 

其實,後來我才知道有多少值存儲在同一個網格單元格以及它們的總和。但是,對100000+以上的長度數組執行此操作會變得非常慢。有沒有使用for循環的另一種方法?

是一種方法類似,這可能嗎?我知道這還沒有工作。

gridarray[rows,cols] += data 
gridarray_counts[rows,cols] += 1 
+0

只是爲了向未來的讀者闡明,看起來很簡單的解決方案,聲明不起作用,確實不起作用,因爲'行,列'包含重複的索引。有關更多詳細信息,請參閱[此問題](http://stackoverflow.com/questions/16034672/how-do-numpys-in-place-operations-e-g-work)。 – shx2

回答

2

我會用bincount這一點,但現在bincount只需要1darrays所以你需要編寫自己的ndbincout,是這樣的:

def ndbincount(x, weights=None, shape=None): 
    if shape is None: 
     shape = x.max(1) + 1 

    x = np.ravel_multi_index(x, shape) 
    out = np.bincount(x, weights, minlength=np.prod(shape)) 
    out.shape = shape 
    return out 

然後,你可以這樣做:

gridarray = np.zeros([3,3]) 

cols = np.random.random_integers(0,2,15) 
rows = np.random.random_integers(0,2,15) 
data = np.random.random_integers(0,9,15) 

x = np.vstack([rows, cols]) 
temp = ndbincount(x, data, gridarray.shape) 
gridarray = gridarray + temp 
gridarray_counts = ndbincount(x, shape=gridarray.shape) 
+0

完美工作,比for循環分配方法快10倍。 – HyperCube

0

您可以直接做到這一點:

gridarray[(rows,cols)]+=data 
gridarray_counts[(rows,cols)]+=1 
+0

不幸的是,這不會導致相同的(正確)的輸出。 – HyperCube

+0

@HyperCube啊好的,我假設了唯一的索引。我會保留這個答案,以防其他人可能有獨特的指標。 – Bitwise