0

Suppose we have a distance matrix as following:

array([[ 0.        ,  0.2039889 ,  0.25030506,  0.56118992],
       [ 0.2039889 ,  0.        ,  0.39916797,  0.6909994 ],
       [ 0.25030506,  0.39916797,  0.        ,  0.63389566],
       [ 0.56118992,  0.6909994 ,  0.63389566,  0.        ]])

How can I get the values of the upper matrix with their indexes like :

1       0.2039889   1   2
2       0.25030506  1   3
3       0.56118992  1   4
4       0.39916797  2   3
5       0.6909994   2   4
6       0.63389566  3   4 
Noor
  • 365
  • 2
  • 13
  • 1
    Assuming that your array as a numpy array, you can use tril_indices to give you a tuple of array indices for the upper array and then use them to extract the values. – closetCoder Dec 30 '17 at 23:19

2 Answers2

1

For the upper triangle, use triu_indices with diagonal offset 1 to exclude the main diagonal (based on the suggestion by closetCoder):

a = # your array
idx = np.triu_indices(a.shape[0], 1)   # indices
stacked = np.concatenate((
                          a[idx].reshape(-1, 1),   # reshaped as column of values
                          np.array(idx).T + 1      # transposed as columns of indices
                         ), axis=1)

Adding 1 because apparently you want 1-based indices.

If the numbers 1,2,3,4,... on the left are also needed, that's another thing to concatenate:

stacked = np.concatenate((
                          np.arange(idx[0].size).reshape(-1, 1) + 1,    # numbers
                          a[idx].reshape(-1, 1), 
                          np.array(idx).T + 1
                         ), axis=1)

Looks like this:

array([[ 1.        ,  0.2039889 ,  1.        ,  2.        ],
       [ 2.        ,  0.25030506,  1.        ,  3.        ],
       [ 3.        ,  0.56118992,  1.        ,  4.        ],
       [ 4.        ,  0.39916797,  2.        ,  3.        ],
       [ 5.        ,  0.6909994 ,  2.        ,  4.        ],
       [ 6.        ,  0.63389566,  3.        ,  4.        ]])

Just for completeness, I'll mention scipy.spatial.distance.squareform which gets the values as above, but not the indexes.

0

Here's one way to solve it using np.triu_indices

# 4 - matrix shape, 1 is diagonal offset
In [67]: idxs = np.triu_indices(4, 1)

In [68]: entries = arr[idxs]

In [69]: one_based_idxs = [ ar+1 for ar in idxs]

In [70]: one_based_idxs
Out[70]: [array([1, 1, 1, 2, 2, 3]), array([2, 3, 4, 3, 4, 4])]

In [71]: entries
Out[71]: 
array([ 0.2039889 ,  0.25030506,  0.56118992,  0.39916797,  0.6909994 ,
        0.63389566])
kmario23
  • 57,311
  • 13
  • 161
  • 150