2012-11-25 37 views
2

在NumPy的,非broadcastable輸出操作數numpy的2D澆鑄成3D

foo = np.array([[i+10*j for i in range(10)] for j in range(3)]) 
    array([[ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9], 
      [10, 11, 12, 13, 14, 15, 16, 17, 18, 19], 
      [20, 21, 22, 23, 24, 25, 26, 27, 28, 29]]) 
    filter = np.nonzero(foo > 100)#nothing matches 

    foo[:,filter] 
    array([], shape=(3, 2, 0), dtype=int64) 

    foo[:,0:0] 
    array([], shape=(3, 0), dtype=int64) 

filter2 = np.nonzero(np.sum(foo,axis=0) < 47) 
foo[:,filter2] 
array([[[ 0, 1, 2, 3, 4, 5]], 

     [[10, 11, 12, 13, 14, 15]], 

     [[20, 21, 22, 23, 24, 25]]]) 
foo[:,filter2].shape 
(3, 1, 6) 

我有一個「過濾器」狀態,我想在對所有匹配的列中的所有行執行操作,但如果過濾器是一個空數組,不知何故,我的foo [:,filter]被廣播到3D數組中。另一個例子是filter2 - > again,foo [:,filter2]給我一個3D數組,當我期待foo [:,(np.sum(foo,axis = 0)< 47)]

有人可以解釋一下np.nonzero的正確用例與使用布爾值來查找正確的列/索引的比較嗎?

回答

1

首先,foo[filter] == foo[filter.nonzero()]filter是一個布爾數組。

要理解爲什麼你會得到意想不到的結果,你必須瞭解一點python如何索引。要在python中執行多維索引,您可以使用[]中的索引,用逗號分隔或使用元組。所以foo[1, 2, 3]foo[(1, 2, 3)]相同。考慮到這一點,請看看當你做foo[:, something]會發生什麼。我相信你的例子是你想要得到foo[:, something[0], something[1]],但是你得到了foo[(slice[None], (something[0], something[1]))]

這一切都有點學術性,因爲如果你只是使用filter進行索引,你可能不需要使用非零值,只需使用布爾數組作爲索引,但如果需要的話,你可以執行如下操作:

foo[:, filter[0]] 

# OR 
index = (slice(None),) + filter.nonzero() 
foo[index]