1

I have a condensed distance matrix from scipy that I need to pass to a C function that requires the matrix be converted to the lower triangle read by rows. For example:

0 1 2 3 
  0 4 5 
    0 6
      0 

The condensed form of this is: [1,2,3,4,5,6] but I need to convert it to

0
1 0
2 4 0
3 5 6 0

The lower triangle read by rows is: [1,2,4,3,5,6].

I was hoping to convert the compact distance matrix to this form without creating a redundant matrix.

GWW
  • 43,129
  • 11
  • 115
  • 108

1 Answers1

4

Here's a quick implementation--but it creates the square redundant distance matrix as an intermediate step:

In [128]: import numpy as np

In [129]: from scipy.spatial.distance import squareform

c is the condensed form of the distance matrix:

In [130]: c = np.array([1, 2, 3, 4, 5, 6])

d is the redundant square distance matrix:

In [131]: d = squareform(c)

Here's your condensed lower triangle distances:

In [132]: d[np.tril_indices(d.shape[0], -1)]
Out[132]: array([1, 2, 4, 3, 5, 6])

Here's a method that avoids forming the redundant distance matrix. The function condensed_index(i, j, n) takes the row i and column j of the redundant distance matrix, with j > i, and returns the corresponding index in the condensed distance array.

In [169]: def condensed_index(i, j, n):
     ...:     return n*i - i*(i+1)//2 + j - i - 1
     ...: 

As above, c is the condensed distance array.

In [170]: c
Out[170]: array([1, 2, 3, 4, 5, 6])

In [171]: n = 4

In [172]: i, j = np.tril_indices(n, -1)

Note that the arguments are reversed in the following call:

In [173]: indices = condensed_index(j, i, n)

indices gives the desired permutation of the condensed distance array.

In [174]: c[indices]
Out[174]: array([1, 2, 4, 3, 5, 6])

(Basically the same function as condensed_index(i, j, n) was given in several answers to this question.)

Warren Weckesser
  • 110,654
  • 19
  • 194
  • 214
  • Thanks, I was hoping to avoid it, because my matrix is quite large (10k - 20k rows), but at least I can use this. – GWW Jun 06 '17 at 01:20
  • Thanks a lot. I read that question earlier and for some reason my brain didn't put it together. – GWW Jun 06 '17 at 02:47