numpy:ravel_multi_index 通过迭代索引循环增加不同的结果

numpy: ravel_multi_index increment different results from iterating over indices loop

我有一个索引数组(可能重复),我将另一个二维矩阵中的每个索引递增 1。有几个建议,这个 answer 建议使用 np.ravel_multi_index .

所以,我试过了,但他们似乎没有给我相同的答案。知道为什么吗?

raveled = np.ravel_multi_index(legit_indices.T, acc.shape)
counts = np.bincount(raveled)
acc = np.resize(counts, acc.shape)

acc2 = np.zeros(acc2.shape)
for i in legit_indices:
    acc2[i[0], i[1]] += 1

(Pdb) np.array_equal(acc, acc2)
False

(Pdb) acc[493][5]
135
(Pdb) acc2[493][5]
0.0

您当前的方法存在一些问题。首先,np.bincount(x) 将为您提供 每个 正整数值的计数 x 从 0 开始 结束于 max(x):

print(np.bincount([1, 1, 3, 3, 3, 4]))
# [0, 2, 0, 3, 1]
# i.e. [count for 0, count for 1, count for 2, count for 3, count for 4]

因此,如果不是 acc.flat 中的每个位置都被索引,则 np.bincount(raveled) 将大于唯一索引的数量。什么 您实际上 想要的是 acc.flat 中那些位置的计数 至少索引一次。

其次,您要做的是将 bin 计数分配给相应的 索引到 acc.flat。你对 np.resize 的调用是重复部分 你的 bincounts 数组,以使其与 acc.flat 的大小相同, 然后将其重塑为与 acc 相同的形状。这不会导致垃圾箱 计数被分配到 acc!

中的正确位置

我解决这个问题的方法是使用 np.unique 而不是 np.bincount,并将其用于 return 唯一索引及其对应 计数。然后可以使用这些将正确的计数分配给 acc:

中正确的唯一位置
import numpy as np

# some example data
acc = np.zeros((4, 3))
legit_indices = np.array([[0, 1],
                          [0, 1],
                          [1, 2],
                          [1, 0],
                          [1, 0],
                          [1, 0]])

# convert the index array into a set of indices into acc.flat
flat_idx = np.ravel_multi_index(legit_indices.T, acc.shape)

# get the set of unique indices and their corresponding counts
uidx, ucounts = np.unique(flat_idx, return_counts=True)

# assign the count value to each unique index in acc.flat
acc.flat[uidx] = ucounts

# confirm that this matches the result of your for loop
acc2 = np.zeros_like(acc)
for ii, jj in legit_indices:
    acc2[ii, jj] += 1

assert np.array_equal(acc, acc2)