Executando operações em um Arrray Numpy, mas valores de mascaramento ao longo da diagonal a partir dessas operações
Pergunta
Como posso executar operações em matrizes, isso não faz nada na diagonal é calculado de modo que todos, exceto a 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 o valor da NAN, mas manteve o valor zero na diagonal em todas as respostas
Solução
Eu me pergunto se as matrizes mascaradas podem fazer o que você quiser, por exemplo,
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)
A outra maneira de fazer isso é, é claro, para converter primeiro os nans em 0s e depois mascarar os 0s:
NP.nan_to_num(A)
MA.masked_equal(A, 0)
Finalmente, muitas vezes é eficiente mascarar e converter os Nans em uma etapa:
MA.fix_invalid(A)
Muito direto, lembre -se de que 'ma' pode ainda não estar no seu espaço para nome e também que essas funções lidam com 'Nans' e 'INFS', que geralmente é o que você deseja.
Outras dicas
>>> 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 do que você precisa calcular
Faça seu cálculo normalmente e depois
myarray[arange(len(array)), arange(len(array))] = 0.
Você pode simplesmente fazer o cálculo normalmente e depois definir a diagonal de volta para zero?