Realizar operaciones en una matriz NumPy pero enmascarar valores a lo largo de la diagonal de estas operaciones

StackOverflow https://stackoverflow.com/questions/1803860

  •  05-07-2019
  •  | 
  •  

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

¿Fue útil?

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?

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top