Search code examples
pythonpython-3.xadjacency-matrixadjacency-list

How to convert an adjacency list into an adjacency matrix in Python


I have an adjacency list like this:

0 1 4 5
1 0 2 6
2 1 3 7
3 2 4 8
4 0 3 9
5 0 7 8
6 1 8 9
7 2 5 9
8 3 5 6
9 4 6 7

Where the first row is saying 0 is adjacent to 1, 4, and 5; the second row is saying 1 is adjacent to 0, 2, and 6; the third row is saying 2 is adjacent to 1, 3, and 7, ...

How can I convert it into an adjacency matrix like so?

0 1 0 0 1 1 0 0 0 0
1 0 1 0 0 0 1 0 0 0
0 1 0 1 0 0 0 1 0 0
0 0 1 0 1 0 0 0 1 0
1 0 0 1 0 0 0 0 0 1
1 0 0 0 0 0 0 1 1 0
0 1 0 0 0 0 0 0 1 1
0 0 1 0 0 1 0 0 0 1
0 0 0 1 0 1 1 0 0 0
0 0 0 0 1 0 1 1 0 0

Solution

  • How about creating lists of positioned 0s and 1s, of same length, inside the dataframe and then pulling them out as series.

    # the lists will all be this length
    maxlen = df.max().max()
    
    df = pd.DataFrame([
        [0, 1, 4, 5],
        [1, 0, 2, 6],
        [2, 1, 3, 7],
        [3, 2, 4, 8],
        [4, 0, 3, 9],
        [5, 0, 7, 8],
        [6, 1, 8, 9],
        [7, 2, 5, 9],
        [8, 3, 5, 6],
        [9, 4, 6, 7]])
    
    # the function used to create the lists
    def createlist(x):
        arr=(maxlen+1)*[0]
        arr[x]=1
        return arr
    
    # create the list for each cell, then concatenate the lists per row vertically, sum them, giving each final row
    df2 = df.applymap(createlist).apply(lambda x: pd.concat([pd.Series(x[i]) for i in range(len(df.columns))], axis=1).sum(axis=1),axis=1)
    
    
    df2
    
        0   1   2   3   4   5   6   7   8   9
    0   1   1   0   0   1   1   0   0   0   0
    1   1   1   1   0   0   0   1   0   0   0
    2   0   1   1   1   0   0   0   1   0   0
    3   0   0   1   1   1   0   0   0   1   0
    4   1   0   0   1   1   0   0   0   0   1
    5   1   0   0   0   0   1   0   1   1   0
    6   0   1   0   0   0   0   1   0   1   1
    7   0   0   1   0   0   1   0   1   0   1
    8   0   0   0   1   0   1   1   0   1   0
    9   0   0   0   0   1   0   1   1   0   1
    

    To set the diagonal to zeroes do something like:

    df3 = df2.values
    
    np.fill_diagonal(df3, 0)