Fast counting of interactions between groups given users interactions and groups assignments
Re-formulating the problem into a matrix multiplication one speeds up the algorithm very much.

Algebra:

Create a matrix G of n_groups x n_users such that every column is a group mask, that is, all users (columns) that belong to that group (row) are flagged are 1 and 0 otherwise. If Y is the matrix of interactions, then the interactions between every pair of groups can be obtained by the following equation:

$$I = GYG^T$$

Code:

The code is:

import numpy as np
from numpy import dot

def test3(y, c):

    N = len(c)
    C = len(set(c))
    noty = np.mod(y+1,2)

    # create C group masks of 1 (if user is belongs to group) and 0. 
    G = np.zeros((C,N))
    for group in range(C):
        G[group] = [1 if c_== group else 0 for c_ in c]

    # Groups (src) * interaction_matrix * Groups_transposed (dst)
    # Every row of Groups matrix is the mask of a group
    return dot(dot(G,y),G.T), dot(dot(G,noty),G.T)


1000 loops, best of 3: 810 µs per loop