Search code examples
pythonpandasnumpynetworkxadjacency-matrix

How can I convert a two column array to a matrix with counts of occurences?


I have the following numpy array:

import numpy as np

pair_array = np.array([(205, 254), (205, 382), (254, 382), (18, 69), (205, 382), 
                       (31, 183), (31, 267), (31, 382), (183, 267), (183, 382)])

print(pair_array)

#[[205 254]
# [205 382]
# [254 382]
# [ 18  69]
# [205 382]
# [ 31 183]
# [ 31 267]
# [ 31 382]
# [183 267]
# [183 382]]

Is there a way to transform this array to a symmetric pandas Dataframe that contains the count of occurences for all possible combinations? I expect something along the lines of this:

#     18  31  69 183 205 254 267 382 
#  18  0   0   1   0   0   0   0   0
#  31  0   0   0   1   0   0   1   1
#  69  1   0   0   0   0   0   0   0
# 183  0   1   0   0   0   0   1   1
# 205  0   0   0   0   0   1   0   2
# 254  0   0   0   0   1   0   0   1
# 267  0   1   0   1   0   0   0   0
# 382  0   1   0   1   2   1   0   0

Solution

  • One way could be to build a graph using NetworkX and obtain the adjacency matrix directly as a dataframe with nx.to_pandas_adjacency. To account for the co-occurrences of the edges in the graph, we can create a nx.MultiGraph, which allows for multiple edges connecting the same pair of nodes:

    import networkx as nx
    
    G = nx.from_edgelist(pair_array, create_using=nx.MultiGraph)
    nx.to_pandas_adjacency(G, nodelist=sorted(G.nodes()), dtype='int')
    
          18   31   69   183  205  254  267  382
    18     0    0    1    0    0    0    0    0
    31     0    0    0    1    0    0    1    1
    69     1    0    0    0    0    0    0    0
    183    0    1    0    0    0    0    1    1
    205    0    0    0    0    0    1    0    2
    254    0    0    0    0    1    0    0    1
    267    0    1    0    1    0    0    0    0
    382    0    1    0    1    2    1    0    0
    

    Building a NetworkX graph, will also enable to create an adjacency matrix or another depending on the behaviour we expect. We can either create it using a:

    • nx.Graph: If we want to set to 1 both entries (x,y) and (y,x) for a (x,y) (or (y,x)) edge. This will hence produce a symmetric adjacency matrix
    • nx.DiGraph: If (x,y) should only set the (x,y) the entry to 1
    • nx.MultiGraph: For the same behaviour as a nx.Graph but accounting for edge co-occurrences
    • nx.MultiDiGraph: For the same behaviour as a nx.DiGraph but also accounting for edge co-occurrences