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...