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)
我有一个索引数组(可能重复),我将另一个二维矩阵中的每个索引递增 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)