2 回答

TA貢獻1884條經驗 獲得超4個贊
在 MATLAB 中,使用 2 個列表(實際上是矩陣)進行索引會選擇一個塊。 numpy另一方面,嘗試相互廣播索引數組,并返回選定的點。它的行為sub2ind與 MATLAB 中的行為接近。
In [971]: arr = np.arange(16).reshape(4,4)
In [972]: arr
Out[972]:
array([[ 0, 1, 2, 3],
[ 4, 5, 6, 7],
[ 8, 9, 10, 11],
[12, 13, 14, 15]])
In [973]: i1, i2 = np.array([0,2,3]), np.array([1,2,0])
使用 2 個相同大小的一維數組進行索引:
In [974]: arr[i1,i2]
Out[974]: array([ 1, 10, 12])
這實際上[arr[0,1], arr[2,2], arr[3,0]]為匹配索引的每個點返回一個元素。
但是如果我把一個索引變成一個“列向量”,它會從行中i2選擇,而從列中選擇。
In [975]: arr[i1[:,None], i2]
Out[975]:
array([[ 1, 2, 0],
[ 9, 10, 8],
[13, 14, 12]])
MATLAB 使塊索引變得容易,而單獨訪問則更難。numpy盡管底層機制是相同的,但在塊中訪問有點困難。
使用您的示例i1[0],i2[0]可以是如下數組:
array([0, 2]), array([3])
(2,) (1,)
形狀 (1,) 數組也可以與 (2,) 或 (2,1) 數組一起廣播。如果代替代碼將失敗is[0]是np.array([0,1,2]),A(3)陣列,其不能與(2)陣列對。但是對于 (2,1) 它會產生一個 (2,3) 塊。

TA貢獻1818條經驗 獲得超8個贊
您可以使用np.ix_獲取 matlab-ish 行為:
A = np.arange(9).reshape(3, 3)
A[[1,2],[0,2]]
# array([3, 8])
A[np.ix_([1,2],[0,2])]
# array([[3, 5],
# [6, 8]])
在np.ix_幕后,@hpaulj 詳細描述了以下內容:
np.ix_([1,2],[0,2])
# (array([[1],
# [2]]), array([[0, 2]]))
您可以將其應用于您的特定問題,如下所示:
M = np.random.randint(0, 10, (n, n))
M
# array([[6, 2, 7, 1],
# [6, 7, 9, 5],
# [9, 4, 3, 2],
# [3, 1, 7, 9]])
idx = np.array([0, 1, 0, 2])
ng = idx.max() + 1
out = np.zeros((ng, ng), M.dtype)
np.add.at(out, np.ix_(idx, idx), M)
out
# array([[25, 6, 3],
# [15, 7, 5],
# [10, 1, 9]])
順便說一句:有一個更快但不太明顯的解決方案,它依賴于平面索引:
np.bincount(np.ravel_multi_index(np.ix_(idx, idx), (ng, ng)).ravel(), M.ravel(), ng*ng).reshape(ng, ng)
# array([[25., 6., 3.],
# [15., 7., 5.],
# [10., 1., 9.]])
添加回答
舉報