Numpy: ravel_multi_index increases different results from iterating over an index cycle

I have an array of indices (possible duplicates) where I increment each of these indices in another 2D matrix by 1. There were several suggestions and this answer suggests using np.ravel_multi_index .

So I tried this, but they don't seem to give me the same set of answers. Any idea why?

 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 
0
source share
1 answer

There are several issues with your current approach. Firstly, np.bincount(x) will give you counts for each positive integer value of x starting at 0 and ending with max(x) :

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

Therefore, if not all indices in acc.flat indexed, the length of np.bincount(raveled) will be greater than the number of unique indices. Whatever you really want, these are counts only for places in acc.flat that are indexed at least once.

Secondly, what you want to do is assign the bin account to the corresponding indexes in acc.flat . Your np.resize call is to repeat parts of your binson array to make it the same size as acc.flat , then change it to the same shape as acc . This will not cause the recycle bin to be assigned to the correct locations in acc !

As I solved this problem, it would be to use np.unique instead of np.bincount and use it to return both unique indices and their corresponding ones to the account. They can then be used to assign the correct counts to the correct unique locations within 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
source

Source: https://habr.com/ru/post/976607/


All Articles