Esecuzione di operazioni su un array NumPy ma mascherando i valori lungo la diagonale da queste operazioni
Domanda
poiché posso eseguire operazioni su array in modo che non faccia nulla sulla diagonale è calcolato in modo tale che tutti tranne la diagonale
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. ]])
per evitare il valore NaN, ma ha mantenuto il valore zero sulla diagonale in tutte le risposte
Soluzione
Mi chiedo se gli array mascherati potrebbero fare quello che vuoi, ad esempio
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)
L'altro modo per farlo è, ovviamente, per prima cosa convertire i NaN a 0, quindi maschera gli 0:
NP.nan_to_num(A)
MA.masked_equal(A, 0)
Infine, spesso è efficace mascherare e convertire i NaN in un solo passaggio:
MA.fix_invalid(A)
Abbastanza semplice, tieni presente che 'ma' potrebbe non essere ancora nel tuo spazio dei nomi e anche che queste funzioni si occupano di 'NaNs' e 'infs', che di solito è quello che vuoi.
Altri suggerimenti
>>> 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
Dipende da cosa devi calcolare
Esegui i tuoi calcoli normalmente e poi
myarray[arange(len(array)), arange(len(array))] = 0.
Puoi semplicemente fare il calcolo normalmente, quindi in seguito riportare la diagonale a zero?