没有fill_diagonal的inf的Python矩阵对角线 [英] Python matrix diagonal of inf without fill_diagonal
问题描述
我需要将矩阵的对角元素设置为Inf.
一种简单的方法是使用np.fill_diagonal
.
np.fill_diagonal(my_matrix, float('inf')
但是fill_diagonal
修改输入矩阵,而不是返回填充对角线的新矩阵.
这对我不起作用.我需要在不修改原始矩阵的情况下填充对角线.
当然我可以克隆原始矩阵,所以我将始终保留原始矩阵的副本.但是,我不太喜欢这种解决方案,因为我会经常更新原始矩阵,因此每次需要对角线为inf时,都必须对其进行复制.
是否有一个功能与fill_diagonal
相同但不修改输入矩阵?像这样:
new_matrix = np.fill_diagonal(original_matrix, float('inf')
为什么我需要这个:
我的矩阵是点之间的距离矩阵,我想在每一步中计算两个最近的点.当然,此矩阵的对角线为0(因为从点到自身的距离为0).因此,要确保我不会接受相同的观点,我的解决方案是将对角线设置为Inf.
但是,一旦找到两个点,我需要计算这两个点与其余点之间的平均距离,因此我实际上需要对角线为0而不是Inf.
当前我正在做的是
- 用Inf填充对角线
- 找到2个最接近的点
- 用0填充对角线
-
计算这两个点之间以及其余两个点之间的平均距离.
# 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
但是,我不喜欢将对角线设置为Inf然后返回0的想法,我宁愿仅将函数传递给argmax
,该函数返回用Inf填充对角线的数据,而无需实际修改矩阵数据.>
类似的东西:
idx = np.argmin(return_filled_diagonals(data, float('Inf'))
# here I can operate with data as usual since it has not been modified.
orig_mat = np.array([[1.2,2,3],[4,5,6],[7,8,9]])
#set diagonal to inf without making a copy of the array.
orig_mat + np.where(np.eye(orig_mat.shape[0])>0,np.inf,0)
array([[ inf, 2., 3.],
[ 4., inf, 6.],
[ 7., 8., inf]])
#the original array remains untorched.
print(orig_mat)
[[ 1.2 2. 3. ]
[ 4. 5. 6. ]
[ 7. 8. 9. ]]
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.
orig_mat = np.array([[1.2,2,3],[4,5,6],[7,8,9]])
#set diagonal to inf without making a copy of the array.
orig_mat + np.where(np.eye(orig_mat.shape[0])>0,np.inf,0)
array([[ inf, 2., 3.],
[ 4., inf, 6.],
[ 7., 8., inf]])
#the original array remains untorched.
print(orig_mat)
[[ 1.2 2. 3. ]
[ 4. 5. 6. ]
[ 7. 8. 9. ]]
这篇关于没有fill_diagonal的inf的Python矩阵对角线的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!