2012-03-20 12 views
6

Diciamo che ho una classe chiamata Star che ha un attributo color. Posso ottenere il colore con star.color.Ottenere attributi da matrici di oggetti in NumPy

Ma cosa succede se ho un array NumPy di ​​questi oggetti Star. Qual è il modo preferito per ottenere una matrice di colori?

posso farlo con

colors = np.array([s.color for s in stars]) 

Ma è questo il modo migliore per farlo? Sarebbe bello se potessi fare semplicemente colors = star.color o colors = star->color come in altre lingue. C'è un modo semplice per fare questo in numpy?

+0

possibile duplicato di [numpy array of objects] (http://stackoverflow.com/questions/4877624/numpy-array-of-objects) – YXD

risposta

7

La cosa più vicina a ciò che si desidera è di usare un recarray invece di un ndarray di oggetti Python:

num_stars = 10 
dtype = numpy.dtype([('x', float), ('y', float), ('colour', float)]) 
a = numpy.recarray(num_stars, dtype=dtype) 
a.colour = numpy.arange(num_stars) 
print a.colour 

stampe

[ 0. 1. 2. 3. 4. 5. 6. 7. 8. 9.] 

utilizzando una matrice NumPy di ​​oggetti Python di solito è meno efficiente di un semplice list, mentre un recarray memorizza i dati in un formato più efficiente.

+0

Cool. Quindi li rende come array di strutture IDL che è quello che volevo. Come posso usarlo se ho già una classe Python regolare definita? C'è un modo semplice per farlo? – Dave31415

+0

@ Dave31415: IDL? Quindi sei un astronomo, o qualcuno * al di fuori * l'astronomia usa davvero questo? Per quanto riguarda la tua domanda: senza vedere la definizione della classe, questo è un po 'difficile da rispondere. Usando NumPy, in genere non si desidera che i "metodi" operino su singoli record, ma piuttosto funzioni che possano operare su tutto l'array contemporaneamente. Quindi avresti bisogno di vettorializzare i tuoi metodi. –

+0

Cercando di essere un ex-astronomo. Quindi immagino che quello che stai dicendo sia che gli array di oggetti non sono la struttura dati preferita per numpy. Ma allora cos'è? Posso creare Classi i cui attributi sono array numpy. E 'il modo migliore? Non sembra quello che voglio. – Dave31415

3

È possibile utilizzare numpy.fromiter(s.color for s in stars) (notare la mancanza di parentesi quadre). Ciò eviterà di creare la lista intermedia, che immagino ti possa interessare se usi numpy.

(Grazie a @SvenMarnach e @DSM per le loro correzioni di seguito).

+2

Sfortunatamente non funzionerà: otterrete qualcosa come 'array ( a 0x9cff34c>, dtype = oggetto)'. (Una volta avevo un bug nel mio codice che alla fine era dovuto al fatto che pensavo che avrebbe funzionato.) – DSM

+1

Dovresti usare 'numpy.fromiter()' per questo. –

+2

Nota: per farlo funzionare in numpys recenti, è necessario 'numpy.fromiter ((s.color per s nelle stelle), float)'.Inoltre, l'aggiunta di 'count = len (stars)' lo renderà più efficiente per i long array. – Dougal

Problemi correlati