Esecuzione di operazioni su un array NumPy ma mascherando i valori lungo la diagonale da queste operazioni

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

  •  05-07-2019
  •  | 
  •  

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

È stato utile?

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?

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top