2
$\begingroup$

I'm using Scipy's pdist function to calculate a distance matrix which is working great but it gives me a symmetric matrix and I want to convert it into a lower-left triangular matrix.

This is what it prints out for me:

  a   b   c   d
a 0 ### ### ###
b ### 0 ### ###
c ### ### 0 ###
d ### ### ### 0

This is what I want it to be:

###
### ###
### ### ###

I know there's a function in R to do this (upper.tri) but it just replaces everything to the right of the 0 with more 0s. Is there a better/easier way to get it like this? I'm opening the file in excel and removing everything to the right with the 0 manually right now.

$\endgroup$
3
  • 1
    $\begingroup$ From reading the scipy documentation for the pdist function, it seems to suggest it should already only return upper-triangular entries rather than a full matrix. Are you using pdist directly or through some other package? $\endgroup$ Commented Oct 27, 2023 at 20:45
  • $\begingroup$ This is the command I use to calculate the distance: pd.DataFrame(squareform(pdist(kmer_matrix, 'euclidean'))) I convert it into a pandas dataframe so it's easier to output into a file and I use squareform because I read somewhere that it helps space out the final output. $\endgroup$
    – rimo
    Commented Nov 1, 2023 at 15:34
  • $\begingroup$ I just tried running it without squareform and it outputs all the distances in a descending list :/ $\endgroup$
    – rimo
    Commented Nov 1, 2023 at 15:42

2 Answers 2

4
$\begingroup$

NumPy has a convenient built-in function for accessing the lower-triangular or upper-trianglar entries of an array. To get the lower-triangular entries, you can use numpy.tril_indices to get the indices of these entries, and then use these indices to extract the entries.

import numpy as np

ar = np.array(
    [[0, 1, 2],
    [3, 4, 5],
    [6, 7, 8]]
)
idx = np.tril_indices(3, -1)
ar[idx]
# outputs array([3, 6, 7])

This doesn't automatically produce the spacing you want, but formatting the final display is likely context-dependent.

$\endgroup$
1
  • $\begingroup$ This could work for now thank you!!! $\endgroup$
    – rimo
    Commented Nov 1, 2023 at 15:43
1
$\begingroup$

There seems to be a scipy method that retains the lower triangle but with the 0s. See: https://docs.scipy.org/doc/scipy/reference/generated/scipy.sparse.tril.html#scipy.sparse.tril

$\endgroup$
1
  • $\begingroup$ Thanks! This is pretty helpful too $\endgroup$
    – rimo
    Commented Nov 1, 2023 at 15:43

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.