python - Count occurences of elements of a matrix fast -


let m , n d x d- , d-dimensonal numpy arrays of integers, respectively. want count number of triples of form (n(i), n(j), m(i,j)). result want numpy array such each entry counts number of occurences of such triple.

edit: m symmetric , don't want count triples i=j.

i'm using itertools.product (for loop on pairs) , numpy.bincount this, slow. there smarter way doing this, using numpy?

since arrays contain integers, can consider each triplet linearly index-able element. here's approach philosophy in mind , avoids loops, -

# form n(i) x n(j) array , append "columnar" m(i,j) array nn_arr = n[np.array(list(itertools.product(range(5), repeat=2)))]  nn_m_arr = np.concatenate((nn_arr,m.reshape(-1,1)),axis=1)  # linear indices version dims = nn_m_arr.max(0)+1 lidx = np.ravel_multi_index(nn_m_arr.t,dims)  # unique indices , counts _, idx, counts = np.unique(lidx,return_index=true,return_counts=true)  # corresponding unique triplets using unique indices , zip counts out = zip(map(tuple,nn_m_arr[idx]),counts) 

sample run -

in [206]: m out[206]:  array([[1, 0, 0, 2, 0],        [1, 1, 2, 0, 2],        [0, 0, 2, 0, 1],        [2, 1, 2, 0, 2],        [1, 1, 1, 1, 0]])  in [207]: n out[207]: array([0, 1, 1, 1, 2])  in [208]: out out[208]:  [((0, 0, 1), 1),  ((0, 1, 0), 2),  ((0, 1, 2), 1),  ((0, 2, 0), 1),  ((1, 0, 0), 1),  ((1, 0, 1), 1),  ((1, 0, 2), 1),  ((1, 1, 0), 4),  ((1, 1, 1), 2),  ((1, 1, 2), 3),  ((1, 2, 1), 1),  ((1, 2, 2), 2),  ((2, 0, 1), 1),  ((2, 1, 1), 3),  ((2, 2, 0), 1)] 

Comments