Reputation: 807
For example if i have:
a=np.array([[1,1,4,1,4,3,1]])
We can see that we have the number 1 four times, the number 4 twice and 3 only ones.
I want to have the following result:
array(4,4,2,4,2,1,4)
As you can see: each cell is replaced by the count of it's element.
How can i do it in the best efficient way?
Upvotes: 3
Views: 1410
Reputation: 221604
One vectorized
approach with np.unique
and np.searchsorted
-
# Get unique elements and their counts
unq,counts = np.unique(a,return_counts=True)
# Get the positions of unique elements in a.
# Use those positions to index into counts array for final output.
out = counts[np.searchsorted(unq,a.ravel())]
Sample run -
In [86]: a
Out[86]: array([[1, 1, 4, 1, 4, 3, 1]])
In [87]: out
Out[87]: array([4, 4, 2, 4, 2, 1, 4])
As per the comments from @Jaime, you can use np.unique
alone like so -
_, inv_idx, counts = np.unique(a, return_inverse=True, return_counts=True)
out = counts[inv_idx]
Upvotes: 3
Reputation: 1882
I tried to combine both numpy and Counter:
from collections import Counter
a=np.array([[1,1,4,1,4,3,1]])
# First I count the occurence of every element and stor eit in the dict-like counter
# Then I take its get-method and vectorize it for numpy-array usage
vectorized_counter = np.vectorize(Counter(a.flatten()).get)
vectorized_counter(a)
Out:
array([[4, 4, 2, 4, 2, 1, 4]])
Upvotes: 0
Reputation: 3991
Use a collections.Counter
:
from collections import Counter
ctr = Counter(a.flat)
result = np.array([ctr[i] for i in a.flat])
If you want your result
to have the same dimensions as a
, use reshape
:
result = result.reshape(a.shape)
Upvotes: 0