假設我有一個陣列:
x = np.array([[0, 1, 2],
[3, 4, 5],
[6, 7, 8]])
還有一個多標簽面具:
labels = np.array([[0, 0, 2],
[1, 1, 2],
[1, 1, 2]])
我的目標是將 的條目x匯總在一起,按labels. 例如:
n_labels = np.max(labels) 1
out = np.empty(n_labels)
for label in range(n_labels):
mask = labels == label
out[label] = np.sum(x[mask])
>>> out
np.array([1, 20, 15])
但是,隨著x變n_labels大,我認為這是低效的。每次迭代,您只是將 的條目數的一小部分相加x,但仍然重新計算所有(在運算式中)的掩碼,然后對所有(在labels運算式中labels == label)進行索引。有沒有更有效的方法來做到這一點并變得更大?xx[mask]xn_labels
uj5u.com熱心網友回復:
您可以使用bincount權重:
np.bincount(labels.ravel(), weights=x.ravel())
出去:
array([ 1., 20., 15.])
uj5u.com熱心網友回復:
你真的沒有理由對 2D 陣列進行操作,所以先解開它們:
labels = labels.ravel()
x = x.ravel()
如果您的標簽已經是索引,則可以與andnp.argsort一起使用:np.diffnp.add.reduceat
index = labels.argsort()
splits = np.r_[0, np.flatnonzero(np.diff(labels[index])) 1]
result = np.add.reduceat(x[index], splits)
labels[index]是排序后的索引。每當這種情況發生變化時,您就會進入一個新組,并且diff是非零的。這就是np.flatnonzero(np.diff(labels[index]))為您找到的。由于reduceat在運行結束后采用停止索引,因此您需要添加一個。np.r_允許您輕松地將零添加到一維陣列,這是reduceat考慮 t 所必需的,并且還添加了零。并且還添加了零。他第一次運行(最后一次始終是自動的)。
在運行之前reduceat,您需要訂購x由 定義的運行labels,這就是這樣x[index]做的。
uj5u.com熱心網友回復:
您可以將 2D 陣列與另一種緩慢且過度設計的方法一起使用np.add.at
sums = np.zeros(labels.max() 1, x.dtype)
np.add.at(sums, labels, x)
sums
輸出
array([ 1, 20, 15])
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/488974.html
上一篇:按值從nd-array中洗掉行
