[Python] Python matrix diagonal of inf without fill_diagonal

Discussão em 'Python' iniciado por Stack, Março 12, 2025.

  1. Stack

    Stack Membro Participativo

    I need to set the diagonal elements of a matrix to Inf.

    An easy way to do it is to use np.fill_diagonal.

    np.fill_diagonal(my_matrix, float('inf')


    However fill_diagonal modifies the input matrix instead of returning a new matrix with the diagonal filled. This doesn't work for me. I need the diagonals filled WITHOUT modifying the original matrix.

    Of course I could clone the original matrix, so I will always keep a copy of the original matrix. However I don't really like this solution, since I will update my original matrix often and therefore I'll have to make copies of it every time I need the diagonal to be inf.

    Is there a function that will do the same that fill_diagonal but without modifying the input matrix? Something like:

    new_matrix = np.fill_diagonal(original_matrix, float('inf')


    Why I need this:

    My matrix is a distance matrix between points and I want to compute at each step the two closest points. Of course the diagonal of this matrix is 0 (since the distance from a point to itself is 0). So my solution to make sure I don't take the same point is to set the diagonals to Inf.

    However once the two points are found, I need to compute the average of the distances between this two points and the rest of the points, so I actually need the diagonals to be 0 instead of Inf.

    Currently what I'm doing is:

    • Fill diagonals with Inf
    • Find the 2 closest points
    • Fill diagonals with 0

    • Compute the average distance between this two points and the rest of them.

      # fill diagonal with Inf to avoid taking the diagonals
      np.fill_diagonal(data, float('inf'))
      # find the minimum distance
      idx = np.argmin(data)
      # fill the diagonals back to 0
      np.fill_diagonal(data, 0.0)
      # get the coordinates of the minimum distance
      row, col = np.unravel_index(idx,data.shape)
      # compute the new node as the average distance between the two points
      new_node = np.mean((data[:,row],data[:,col]),0)
      # replace the first node (row) with the new node
      data[:,row] = new_node
      data[row,:] = new_node.T
      # delete the second node (col) from the matrix
      data = np.delete(data, col, 0) # delete row
      data = np.delete(data, col, 1) # delete column

    However I don't like the idea of setting diagonals to Inf and then back to 0, I would prefer just passing a function to argmax that returns data with diagonal filled with Inf without actually modifying the matrix data.

    Something like:

    idx = np.argmin(return_filled_diagonals(data, float('Inf'))
    # here I can operate with data as usual since it has not been modified.

    Continue reading...

Compartilhe esta Página