2016-11-18 57 views
1

我有幾個嵌套for循環做正確的事情(數組的蒙面副本)。然而,表現太慢,我覺得必須有更好的Pythonic方式來做到這一點。目標是使用掩碼來確定何時從源複製數據,使用coord作爲源的索引。該工程的循環代碼如下:如何用掩碼和索引替換double for-loop?

import numpy as np 
dest = np.zeros((4,4,2)) 
source = range(32) 
source = np.reshape(source,(4,4,2)) 
mask = np.ones((4,4),bool) 
mask[1,0] = 0 
coord = np.ones((4,4,2),int) 

for y in range (0,dest.shape[0]): 
    for x in range (0, dest.shape[1]): 
     if np.all(mask[y,x]): 
      dest[y,x] = source[coord[y,x,0], coord[y,x,1]] 

print dest 

運行後,DEST看起來是這樣的:

[[[ 10. 11.] 
    [ 10. 11.] 
    [ 10. 11.] 
    [ 10. 11.]] 
[[ 0. 0.] 
    [ 10. 11.] 
    [ 10. 11.] 
    [ 10. 11.]] 
[[ 10. 11.] 
    [ 10. 11.] 
    [ 10. 11.] 
    [ 10. 11.]] 
[[ 10. 11.] 
    [ 10. 11.] 
    [ 10. 11.] 
    [ 10. 11.]]] 

source[1,1]因爲mask[1,0]設置爲False被複制到所有的dest,除了dest[1,0]mask的其餘部分是True。任何人都可以告訴我如何用更有效率的東西取代循環?

+0

您是否在尋找處理不同的面具或只是一個你有嗎?如果你只是做這個,你可以直接複製沒有面具。和(大部分)無關,但如果遵循[PEP-8](https://www.python.org/dev/peps/pep-0008/)的慣例或至少函數參數之間和'='之前和之後使用了空格。如果你重構成多個函數,你的代碼也會更容易理解。 – danielunderwood

回答

3

使用numpy.where。您必須爲mask添加一個額外的維度,以便它將broadcast

dest = np.where(mask[:,:,None], source[coord[:,:,0], coord[:,:,1]], dest) 

或者,如果合適:

dest = np.where(mask[:,:,None], source[coord[:,:,0], coord[:,:,1]], np.zeros((4,4,2))) 
+0

這正是我所期待的。我嘗試了各種各樣的東西,但這是我失蹤的面具的額外維度。 – MJK