Saullo Castro - 1 year ago 64
Python Question

# transform the upper/lower triangular part of a symmetric matrix (2D array) into a 1D array and return it to the 2D format

In this question it is explained how to access the

`lower`
and
`upper`
triagular parts of a given matrix, say:

``````m = np.matrix([[11, 12, 13],
[21, 22, 23],
[31, 32, 33]])
``````

Here I need to transform the matrix in a 1D array, which can be done doing:

``````indices = np.triu_indices_from(m)
a = np.asarray( m[indices] )[-1]
#array([11, 12, 13, 22, 23, 33])
``````

After doing a lot of calculations with
`a`
, changing its values, it will be used to fill a symmetric 2D array:

``````new = np.zeros(m.shape)
for i,j in enumerate(zip(*indices)):
new[j]=a[i]
new[j[1],j[0]]=a[i]
``````

Returning:

``````array([[ 11.,  12.,  13.],
[ 12.,  22.,  23.],
[ 13.,  23.,  33.]])
``````

Is there a better way to accomplish this? More especifically, avoiding the Python loop to rebuild the 2D array?

Do you just want to form a symmetric array? You can skip the diagonal indices completely.

``````>>> m=np.array(m)
>>> inds = np.triu_indices_from(m,k=1)
>>> m[(inds[1], inds[0])] = m[inds]
>>> m
array([[11, 12, 13],
[12, 22, 23],
[13, 23, 33]])
``````

Creating a symmetric array from a:

``````>>> new = np.zeros((3,3))
>>> vals = np.array([11, 12, 13, 22, 23, 33])
>>> inds = np.triu_indices_from(new)
>>> new[inds] = vals
>>> new[(inds[1], inds[0])] = vals
>>> new
array([[ 11.,  12.,  13.],
[ 12.,  22.,  23.],
[ 13.,  23.,  33.]])
``````
Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download