亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

在 Python 中對矩陣的選定元素求和

在 Python 中對矩陣的選定元素求和

喵喔喔 2021-12-26 15:44:52
我有一個 [nxn] 矩陣,其中包含屬于不同組的值,以及一個 [1 xn] 向量定義每個元素屬于哪個組。(n 通常 ~1E4, 在這個例子中 n=4)我想計算通過將屬于同一組的所有元素相加而獲得的矩陣。我使用 np.where() 來計算每個組的元素所在的索引。當我使用計算的索引時,我沒有獲得預期的元素,因為我選擇了位置對而不是范圍(我習慣于 Matlab,在那里我可以簡單地選擇 M(idx1,idx2) )。import numpy as npn=4M = np.random.rand(n,n)print(M)# This vector defines to which group each element belongbelongToGroup = np.array([0, 1, 0, 2])nGroups=np.max(belongToGroup);# Calculate a matrix obtained by summing elements belonging to the same groupM_sum = np.zeros((nGroups+1,nGroups+1))for g1 in range(nGroups+1):    idxG1 = np.where(belongToGroup==g1)    for g2 in range(nGroups+1):        idxG2 = np.where(belongToGroup==g2)        print('g1 = ' + str(g1))        print('g2 = ' + str(g2))        print(idxG1[0])        print(idxG2[0])        print(M[idxG1[0],idxG2[0]])        print(np.sum(M[idxG1[0],idxG2[0]]))        M_sum[g1,g2]=np.sum(M[idxG1[0],idxG2[0]])print('')print('Example of the problem:')print('Elements I would like to sum to obtain M_sum[0,0]')print(M[0:2,0:2])print('Elements that are summed instead')print(M[[0,1],[0,1]])問題示例:在上面的例子中,元素 M_sum[0,0] 應該是 M[0,0]、M[0,1]、M[1,0] 和 M[1,1] 的和] 相反,它被計算為 M[0,0] 和 M[1,1] 的總和
查看完整描述

2 回答

?
慕村9548890

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) 塊。


查看完整回答
反對 回復 2021-12-26
?
弒天下

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.]])


查看完整回答
反對 回復 2021-12-26
  • 2 回答
  • 0 關注
  • 335 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號