2015-06-25 119 views
2

我具有的值的例如廣播高級索引numpy的

x = array([[[-0.78867513, -0.21132487, 0.  , 0.78867513, 0.21132487, 0.  , 0.  , 0.  , 0.  ], 
      [ 0.  , -0.78867513, -0.21132487, 0.  , 0.78867513, 0.21132487, 0.  , 0.  , 0.  ], 
      [ 0.  , 0.  , 0.  , -0.78867513, -0.21132487, 0.  , 0.78867513, 0.21132487, 0.  ], 
      [ 0.  , 0.  , 0.  , 0.  , -0.78867513, -0.21132487, 0.  , 0.78867513, 0.21132487]], 
      [[-0.78867513, -0.21132487, 0.  , 0.78867513, 0.21132487, 0.  , 0.  , 0.  , 0.  ], 
      [ 0.  , -0.78867513, -0.21132487, 0.  , 0.78867513, 0.21132487, 0.  , 0.  , 0.  ], 
      [ 0.  , 0.  , 0.  , -0.78867513, -0.21132487, 0.  , 0.78867513, 0.21132487, 0.  ], 
      [ 0.  , 0.  , 0.  , 0.  , -0.78867513, -0.21132487, 0.  , 0.78867513, 0.21132487]]]) 

我想在使用高級索引拉出非零值的數組。我知道非零值的索引,從而

idx = array([[4, 3, 1, 0], 
      [5, 4, 2, 1], 
      [7, 6, 4, 3], 
      [8, 7, 5, 4]]) 

期望的結果會是這樣的

x[idx] = array([[[-0.78867513, -0.21132487, 0.78867513, 0.21132487], 
       [-0.78867513, -0.21132487, 0.78867513, 0.21132487], 
       [-0.78867513, -0.21132487, 0.78867513, 0.21132487], 
       [-0.78867513, -0.21132487, 0.78867513, 0.21132487]], 
       [[-0.78867513, -0.21132487, 0.78867513, 0.21132487], 
       [-0.78867513, -0.21132487, 0.78867513, 0.21132487], 
       [-0.78867513, -0.21132487, 0.78867513, 0.21132487], 
       [-0.78867513, -0.21132487, 0.78867513, 0.21132487]]]) 

實際x陣列是沿着第一維度大得多,但非零結構總是由指示idx所以我需要它沿着第一個維度進行廣播。這可能嗎?

編輯:要清楚x沿着第一維包含嵌套列表4 x 9數組。 idx然後具有非零的行逐行。請注意,在x4 x 9嵌套數組的第一行中,第一行的4 3 1 0條目不爲零。

+0

目前還不清楚'idx'是如何涉及哪些元素是非零的。 – user2357112

+0

添加和編輯以澄清。 – johntfoster

+0

沿'idx'第二軸的元素的順序是否有任何意義?我會期望您所需輸出的元素以不同的順序排列。另外,是否可以保證'x'的結構是這樣的:'idx'不需要鋸齒? – user2357112

回答

1

試試這個:

x[:,np.arange(idx.shape[0])[:,None],idx] 

使用這種技術將在idx中的每一行廣播np.arange(idx.shape[0])[:,None](它具有shape(idx.shape [0],1),因此是列向量)中的每個元素。這將用於x的第一軸上的所有條目。

0

OK,這是一個有點古怪,但在這裏不用...

idxes = np.ones((x.shape[0], x.shape[1], 1), dtype=bool) * idx 
print x[np.array(x, dtype=bool)].reshape(idxes.shape) 

當然,你必須記住寫np.array,而不是array

乾杯!

而且你可以從下面的計算IDX表白自己:

y = x[np.array(x, dtype=bool)] 
print y.reshape(x.shape[0], x.shape[1], y.size/x.shape[0]/x.shape[1]) 

有了這個或它上面的線是浮筒作爲提供,消除了零的面具的bool的鑄造。

0

我試過這個問題的襯墊,它似乎沒有需要idx做這項工作。根據問題的大小,您可能需要更改.reshape()中的參數。

np.array(filter(lambda x: x!=0, x.ravel())).reshape(-1, 4, 4) 

它使陣列變平,除去零,然後將其更改回所需的形狀。

下面是另一個版本,這可能是因爲它不使用filter功能更加高效和使用布爾索引爲numpy的陣列,而不是

y = x.ravel() 
z = y[y!=0].reshape(-1, 4, 4) 

編輯:

雖然與numpy的玩弄我發現了另一種方式來做到這一點。

x[x!=0].reshape(-1, 4, 4) 

而這裏的所有三種方法的性能:

  • 方法1:10000 loops, best of 3: 21.2 µs per loop
  • 方法2:100000 loops, best of 3: 2.42 µs per loop
  • 方法3:100000 loops, best of 3: 1.97 µs per loop
+0

我會感興趣的是,如果像在之前的文章中那樣,將布爾轉換爲布爾類型,並進行平坦化和重塑,它的速度會快於或快於「x!= 0」方法,這種方法涉及到我認爲不同類型的比較。 –

+0

@ MikeO'Connor我試圖分析你的第二種方法,它幾乎是一樣的。這就是我得到了'100000循環,最好的3:每循環2.35微秒' –

+0

非常感謝Lakshay Gang ...我在想,或許鑄造比'x!= 0'更好。 –