2016-06-23 83 views
6

Uso la funzione loadmat di scipy per caricare un file di dati matlab in python.Come accedere agli elementi di numpy ndarray?

from scipy.io import loadmat 

data = loadmat('data.mat') 
fields = data['field'] 

Il tipo di fields è numpy.ndarray:

print 'fields type={}'.format(type(fields)) 
print 'fields dtype={}'.format(fields.dtype) 
print 'fields shape={}'.format(fields.shape) 
fields type=<type 'numpy.ndarray'> 
fields dtype=object 
fields shape=(5,) 

I iterare l'array usando nditer:

for x in np.nditer(fields, flags=['refs_ok']): 
    print 'x={}'.format(x) 
    print 'x type={}'.format(type(x)) 
    print 'x dtype={}'.format(x.dtype) 
    print 'x shape={}'.format(x.shape) 
    break 
x=[u'ACE'] 
x type=<type 'numpy.ndarray'> 
x dtype=object 
x shape=() 

IndexError:

Se provo ad accedere al primo elemento di x ottengo un IndexError:

x[0] 
--------------------------------------------------------------------------- 
IndexError        Traceback (most recent call last) 
<ipython-input-102-8c374ae22096> in <module>() 
    17  print 'type={}'.format(type(x)) 
    18  print 'dtype={}'.format(x.dtype) 
---> 19  x[0] 
    20  break 
    21 

IndexError: too many indices for array 

Domande:

  • Come venire, se type(x) restituisce nump.ndarray dice "troppi indici per array"?
  • Come posso estrarre il contenuto di x in una stringa?

Qui ci sono le versioni che sto usando:

print 'python version: {}'.format(sys.version) 
print 'numpy version: {}'.format(numpy.__version__) 
print 'scipy version: {}'.format(scipy.__version__) 
python version: 2.7.6 (default, Jun 22 2015, 17:58:13) 
[GCC 4.8.2] 
numpy version: 1.11.0 
scipy version: 0.17.1 
+0

È possibile stampare 'x.shape'? –

+0

@C_Z_ - ha aggiornato la domanda per includere 'x.shape', che restituisce'() ' –

+1

Questo è un array 0d, che devi indicizzare con una tupla di elementi 0,' x [()] '. Vedi la mia risposta. – hpaulj

risposta

6

Senza guardare i vostri errori nei dettagli posso sottolineare alcune insidie.

Il .mat conterrà matrici MATLAB (sempre 2d o successive), celle e strutture.

loadmat rende quelli in vari modi. Ci sono dizionari che devi indicizzare per nome. Esistono matrici di oggetti (dtype = oggetto). E ci sono nd array numerici o di stringhe. Potrebbe essere necessario lavorare su più livelli per ottenere l'array numerico.

Controllare la 'forma' (dimensione) di un array e il suo 'dtype'. Se la forma è () e dtype oggetto, quindi estrarla con y=x[()].

Ecco un esempio di una tale matrice di oggetti 0d:

In [4]: y=np.arange(3) 

In [5]: x=np.empty((), dtype=object)  
In [6]: x[()]=y 

In [7]: x 
Out[7]: array(array([0, 1, 2]), dtype=object) 

In [8]: x.shape 
Out[8]:() 

In [9]: x.dtype 
Out[9]: dtype('O') 

In [10]: x[0] 
... 
IndexError: too many indices for array 

In [11]: x[()] 
Out[11]: array([0, 1, 2]) 

x è una matrice 0d (x.ndim), quindi deve essere indicizzato con una tupla 0 elemento, (). Per un programmatore MATLAB che può sembrare strano.

In numpy (Python in generale), x[a,b,c] è lo stesso di x[(a,b,c)] e ind=(a,b,c); x[ind]. In altre parole, gli argomenti in [] sono considerati una tupla di valori.(1,2) è una tupla di 2 elementi, (1,) è un elemento ((1) è solo un raggruppamento) e () è una tupla di elementi 0. Quindi, x[()] è solo un'estensione della normale notazione di indicizzazione nd. Non è un caso speciale.

+0

Grazie, usando quella notazione indicizzazione di array ('x [()]') ha funzionato. Hai una risorsa dove posso leggere su quella notazione? Non l'ho mai visto prima. –

+1

Ho aggiunto un paragrafo su questa notazione. – hpaulj

+0

Capito, grazie per la spiegazione! –