I have a numpy array with letters "a", "b" or "c",
import numpy as np
my_array = np.array(["a", "a", "c", "c", "a"]) # In this example "b" is not present
I want to fuild a function f that counts the unique records of each letter present in the array, for my example f should respond [3, 0, 2] meaning that "a" has appeared 3 times, "b" 0 times and "c" 2 times.
I’m looking for solution (if it possible) that use numpy functions and not explicit for loops over the array. Maybe a kind of group by
>Solution :
Counter from the collections builtin will do that for you.
import numpy as np
my_array = np.array(["a", "a", "c", "c", "a"])
from collections import Counter
cnt = Counter(my_array)
cnt
# Counter({'a': 3, 'c': 2})
Note that it does not provide counts for items which did not appear until you ask for them. At that point the counter will return 0.
>>> cnt['b']
0
If you want to wrap that in a function where you already have a list of keys (not all of which may be present in your array data), that will not populate the 0 counts with keys for you. If you want the 0s and the keys to be populated, something like this:
import numpy as np
from collections import Counter
from typing import Dict, Any
def counter_function(data, keys) -> Dict[Any, int]:
cnt = Counter(data)
for key in keys:
cnt[key] = cnt[key]
return cnt
my_array = np.array(["a", "a", "c", "c", "a"])
so_counter = counter_function(my_array, ["a", "b", "c"])
so_counter
# Counter({'a': 3, 'c': 2, 'b': 0})
will do it for you.