2016-07-19 59 views
0

給定一個WXH的標籤映射,其中每個元素可以從{0,..,K-1}得到值。我想輸出一個尺寸爲KXW×H的標籤張量,其中第K個映射中的每個元素只有1如果labelmap中的對應值是K.目前我的實現使用兩個for循環,並且非常慢。如何加速Numpy中標籤貼圖的標籤張量創建?

p_label = Labelmap with one channel 

label = np.zeros((K,p_label.shape[0], p_label.shape[1])) 
for i in xrange(p_label.shape[0]): 
     for j in xrange(p_label.shape[1]): 
      label[p_label[i,j],i,j] = 1 

有沒有更好的方式來使用廣播在Numpy中執行此操作?

+0

是'p_label' 4D或2? – hpaulj

回答

2

您可以使用==運算符進行廣播。

例如,

In [19]: W = 5 

In [20]: H = 8 

In [21]: K = 10 

創建用於例如p_label

In [22]: p_label = np.random.randint(0, K, size=(W, H)) 

kvals是簡單地將含有[0,1,...,K-1]的數組:

In [23]: kvals = np.arange(K) 

kvals.reshape(-1, 1, 1)kvals轉換爲具有形狀(K, 1,1)。這使用==p_label進行比較。廣播適用,所以比較的結果已經形成(K,W,H)。它是你想要的值的布爾數組。 .astype(int)將結果轉換爲整數數組。 (您可以刪除,如果一個布爾數組會爲你工作。)

In [24]: label = (p_label == kvals.reshape(-1, 1, 1)).astype(int) 

這裏的原p_label。注意,例如,值0的位置:

In [25]: p_label 
Out[25]: 
array([[3, 3, 2, 6, 2, 2, 9, 3], 
     [1, 8, 1, 1, 4, 3, 7, 8], 
     [5, 9, 1, 0, 7, 2, 8, 0], 
     [1, 3, 5, 4, 6, 0, 9, 5], 
     [5, 7, 2, 0, 6, 4, 5, 3]]) 

label[0]處於位置處p_label0 1。

In [26]: label[0] 
Out[26]: 
array([[0, 0, 0, 0, 0, 0, 0, 0], 
     [0, 0, 0, 0, 0, 0, 0, 0], 
     [0, 0, 0, 1, 0, 0, 0, 1], 
     [0, 0, 0, 0, 0, 1, 0, 0], 
     [0, 0, 0, 1, 0, 0, 0, 0]]) 
1
Label[p_label, np.arange(p_label.shape[0])[:,None], np.arange(p_label.shape[1])] = 1 

3個索引陣列相對於彼此的廣播。

==============================

lmap = np.arange(12).reshape(3,4) 
lbl = np.zeros((12,3,4),int) 
lbl[lmap,np.arange(3)[:,None],np.arange(4)] = 1 

In [5]: lbl 
Out[5]: 
array([[[1, 0, 0, 0], 
     [0, 0, 0, 0], 
     [0, 0, 0, 0]], 

     [[0, 1, 0, 0], 
     [0, 0, 0, 0], 
     [0, 0, 0, 0]], 

     ... 
     [[0, 0, 0, 0], 
     [0, 0, 0, 0], 
     [0, 0, 0, 1]]])