Realizar operaciones en una matriz NumPy pero enmascarar valores a lo largo de la diagonal de estas operaciones
Pregunta
ya que puedo realizar operaciones en matrices para que no haga nada en la diagonal se calcula de tal manera que todos menos la diagonal
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. ]])
para evitar el valor de NaN, pero retuvo el valor cero en la diagonal en todas las respuestas
Solución
Me pregunto si las matrices enmascaradas podrían hacer lo que quieres, por ejemplo,
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)
La otra forma de hacerlo es, por supuesto, primero convertir los NaN a 0 y luego enmascarar los 0s:
NP.nan_to_num(A)
MA.masked_equal(A, 0)
Finalmente, a menudo es eficiente enmascarar y convertir los NaN en un solo paso:
MA.fix_invalid(A)
Bastante sencillo, solo tenga en cuenta que 'ma' puede que todavía no esté en su espacio de nombres y que estas funciones se ocupan de 'NaNs' y 'infs', que generalmente es lo que usted desea.
Otros consejos
>>> 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
Depende de lo que necesites calcular
Haz tu cálculo como de costumbre y luego
myarray[arange(len(array)), arange(len(array))] = 0.
¿Puedes simplemente hacer el cálculo de la manera normal, luego, luego, restablecer la diagonal a cero?