簡體   English   中英

numpy arrays 加權計數的快速方法

[英]Fast way for weighted counting of numpy arrays

我有兩個形狀相同的二維 numpy arrays:

idx = np.array([[1, 2, 5, 6],[1, 3, 5, 2]])
val = np.array([[0.1, 0.5, 0.3, 0.2], [0.1, 0., 0.8, 0.2]])

我知道我們可以使用np.bincount設置val作為權重:

np.bincount(idx.reshape(-1), weights=val.reshape(-1))

但這並不是我想要的。 np.bincount將零放在索引不存在的地方。 在示例中,結果是:

array([0. , 0.2, 0.7, 0. , 0. , 1.1, 0.2])

但我不希望這些額外的零用於不存在的索引。 我希望加權計數對應於np.unique(idx)

array([1, 2, 3, 5, 6])

我的預期結果是:

array([0.2, 0.7, 0., 1.1, 0.2])

任何人都有一個想法來有效地做到這一點? 我的idxval非常大,有超過 100 萬個元素。

您可以有效地使用 numpy 庫。

看一下這個:

output = []
for i in np.unique(idx):
    wt = (idx == i)
    if i == 0:
        zeros = wt*(idx+1)
        l = np.sum(zeros*val)
    else:
        zeros = wt*idx
        l = np.sum(zeros*val)/i
    output.append(l)
print(output)

這是相當快的。 我希望它有所幫助。

您可能知道,在 python 中使用 for 循環並不是提高效率的好主意:

您可以嘗試使用 np.unique 方法對 bincount 的 output 進行索引:

>>> np.bincount(idx.reshape(-1), val.reshape(-1))[np.unique(idx)]
array([0.2, 0.7, 0. , 1.1, 0.2])

如果您只想擺脫零,這可能是最快的方法。

成功的關鍵在於:

  • 執行從idx到連續整數的唯一值的映射,從0開始,
  • 根據上述映射的結果計算 bincount,而不是idx本身。

執行此操作的代碼(非常簡潔且沒有任何循環)是:

unq = np.unique(idx)
mapper = pd.Series(range(unq.size), index=unq)
np.bincount(mapper[idx.reshape(-1)], weights=val.reshape(-1))

對於您的樣本數據,結果是:

array([0.2, 0.7, 0. , 1.1, 0.2])

方法一:

np.uniquereturn_inverse=True一起使用。

idx = np.array([[1, 2, 5, 6],[1, 3, 5, 2]])
val = np.array([[0.1, 0.5, 0.3, 0.2], [0.1, 0., 0.8, 0.2]])

unq,inv=np.unique(idx,return_inverse=True)
np.bincount(inv,val.reshape(-1))
# array([0.2, 0.7, 0. , 1.1, 0.2])

方法二:

使用 bincount 然后刪除(真正的)零。

np.bincount(idx.reshape(-1),val.reshape(-1))[np.bincount(idx.reshape(-1)).nonzero()]
# array([0.2, 0.7, 0. , 1.1, 0.2])

哪個更好將取決於idx的分布情況。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM