3
votes

I have a NumPy2d array that is a symmetric matrix (square matrix where the numbers above the diagonal are the same as the number below the diagonal)

Example input matrix:

edgeMatrix = np.array([[0., 2., 9.],
                       [2., 0., 1.],
                       [9., 1., 0.]])

I am looking for a very efficient way to convert this large matrix into a nested dictionary where the first key is the row index of the matrix and the second dict key is the column index of the matrix. ex:

Desired resulting nested dict format:

edgeDict[0][0] = 0
edgeDict[0][1] = 2
edgeDict[0][2] = 9
edgeDict[1][0] = 2
edgeDict[1][1] = 0
edgeDict[1][2] = 1
edgeDict[2][0] = 9
edgeDict[2][1] = 1
edgeDict[2][2] = 0

I have tried using dict(enumerate(edgeMatrix.flatten(), 1)), but failed to figure out how to get the nested aspect of this working.

3
Out of curiosity, why do you want a dict of dict? A list of lists would have the same usage syntax (for reading data/setting existing elements) but would be faster to allocate, smaller in memory footprint and faster in lookup performance. - Matteo Italia
The reason i need a dict and not a list is that this feeds into a package parameter that requires a dict, not a list - user3431083

3 Answers

2
votes

You can create your nested dict using a nested generator expression.

import numpy as np

edgeMatrix = np.array(
    [[0., 2., 9.],
    [2., 0., 1.],
    [9., 1., 0.]]
)

edgeDict = dict(enumerate(dict(enumerate(row)) for row in edgeMatrix))
print(edgeDict)

output

{0: {0: 0.0, 1: 2.0, 2: 9.0}, 1: {0: 2.0, 1: 0.0, 2: 1.0}, 2: {0: 9.0, 1: 1.0, 2: 0.0}}
1
votes

Try this:

In [5]: {i: {j: edgeMatrix[i,j] for (j, _) in enumerate(edgeMatrix[i])} 
for (i, __) in enumerate(edgeMatrix)}

Out[5]: 
{0: {0: 0.0, 1: 2.0, 2: 9.0},
 1: {0: 2.0, 1: 0.0, 2: 1.0},
 2: {0: 9.0, 1: 1.0, 2: 0.0}}
0
votes

pandas does it for you :

In [38]: pd.DataFrame(a).to_dict()
Out[38]: 
{0: {0: 0.0, 1: 2.0, 2: 9.0},
 1: {0: 2.0, 1: 0.0, 2: 1.0},
 2: {0: 9.0, 1: 1.0, 2: 0.0}}