对NumPy数组进行操作,同时屏蔽对角线上的值

2 投票
4 回答
583 浏览
提问于 2025-04-15 16:25

我可以对数组进行操作,让对角线上的元素不受影响,也就是说,计算的时候只处理对角线以外的部分。

array ([[0.,  1.37, 1.,   1.37, 1.,   1.37, 1.]
       [1.37, 0. ,  1.37, 1.73, 2.37, 1.73, 1.37]
       [1. ,  1.37, 0. ,  1.37, 2. ,  2.37, 2. ]
       [1.37, 1.73, 1.37, 0. ,  1.37, 1.73, 2.37]
       [1. ,  2.37, 2. ,  1.37, 0. ,  1.37, 2. ]
       [1.37, 1.73, 2.37, 1.73, 1.37, 0. ,  1.37]
       [1. ,  1.37, 2. ,  2.37, 2. ,  1.37, 0. ]])

这样可以避免出现NaN(不是一个数字)的值,但对角线上的值仍然保留为零,所有的结果中都是这样。

4 个回答

1
>>> arr = [
... [0.,  1.37, 1.,   1.37, 1.,   1.37, 1.],
... [1.37, 0. ,  1.37, 1.73, 2.37, 1.73, 1.37],
... [1. ,  1.37, 0. ,  1.37, 2. ,  2.37, 2. ],
... [1.37, 1.73, 1.37, 0. ,  1.37, 1.73, 2.37],
... [1. ,  2.37, 2. ,  1.37, 0. ,  1.37, 2. ],
... [1.37, 1.73, 2.37, 1.73, 1.37, 0. ,  1.37],
... [1. ,  1.37, 2. ,  2.37, 2. ,  1.37, 0. ]
... ]
>>> for i in range(6):
...     for y in range(6):
...             if (i <> y):
...                     print arr[i][y]*arr[y][i]
...
1.8769
1.0
1.8769
1.0
1.8769
1.8769
1.8769
2.9929
5.6169
2.9929
1.0
1.8769
1.8769
4.0
5.6169
1.8769
2.9929
1.8769
1.8769
2.9929
1.0
5.6169
4.0
1.8769
1.8769
1.8769
2.9929
5.6169
2.9929
1.8769

这要看你需要计算什么了。

1

照常进行你的计算,然后

myarray[arange(len(array)), arange(len(array))] = 0.
2

我想知道“掩码数组”是否能满足你的需求,比如:

import numpy as NP
A = NP.random.random_integers(0, 9, 16).reshape(4, 4)
dg = NP.r_[ [NP.nan] * 4 ]  # proper syntax is 'nan' not 'NaN'
dg = NP.diag(dg)
A += dg                     # a 4x4 array w/ NaNs down the main diagonal
NP.sum(A, axis=1)           # doesn't work, gives: array([ NaN,  NaN,  NaN,  NaN])  
from numpy import ma as MA
Am = **MA.masked_invalid**(A)
NP.sum(Am, axis=1)         # now it works (treats 'nan' as 0)

另一种方法是,先把“NaN”(不是一个数字)转换成0,然后再把0掩盖掉:

NP.nan_to_num(A)
MA.masked_equal(A, 0)

最后,通常可以在一个步骤中同时掩盖和转换“NaN”:

MA.fix_invalid(A)

这很简单,只要记住“ma”可能还不在你的命名空间里,还有这些函数处理的是“NaN”“inf”(无穷大),这通常是你想要的。

撰写回答