2013-07-09 28 views
6

Esiste un modo generale ed efficiente per assegnare valori a un sottoinsieme di un DataFrame nei panda? Ho centinaia di righe e colonne a cui posso accedere direttamente, ma non sono riuscito a capire come modificare i loro valori senza scorrere tra le righe, col paio. Per esempio:Modifica panda DataFrame usando gli indici

In [1]: import pandas, numpy 

In [2]: array = numpy.arange(30).reshape(3,10) 

In [3]: df = pandas.DataFrame(array, index=list("ABC")) 

In [4]: df 
Out[4]: 
    0 1 2 3 4 5 6 7 8 9 
A 0 1 2 3 4 5 6 7 8 9 
B 10 11 12 13 14 15 16 17 18 19 
C 20 21 22 23 24 25 26 27 28 29 

In [5]: rows = ['A','C'] 

In [6]: columns = [1,4,7] 

In [7]: df[columns].ix[rows] 
Out[7]: 
    1 4 7 
A 1 4 7 
C 21 24 27 

In [8]: df[columns].ix[rows] = 900 

In [9]: df 
Out[9]: 
    0 1 2 3 4 5 6 7 8 9 
A 0 1 2 3 4 5 6 7 8 9 
B 10 11 12 13 14 15 16 17 18 19 
C 20 21 22 23 24 25 26 27 28 29 

Credo che ciò che sta accadendo qui è che sto ricevendo una copia piuttosto che una visione, nel senso che non posso assegnare al dataframe originale. È questo il mio problema? Qual è il modo più efficace per modificare quelle righe x colonne (preferibilmente in-pace, dato che DataFrame può occupare molta memoria)?

Inoltre, cosa succede se voglio sostituire quei valori con un DataFrame di forma corretta?

risposta

10

Usa loc in un'espressione di assegnazione (il = significa che non è rilevante se si tratta di una vista o una copia!):

In [11]: df.loc[rows, columns] = 99 

In [12]: df 
Out[12]: 
    0 1 2 3 4 5 6 7 8 9 
A 0 99 2 3 99 5 6 99 8 9 
B 10 11 12 13 14 15 16 17 18 19 
C 20 99 22 23 99 25 26 99 28 29 

Se si utilizza una versione precedente alla 0.11 è possibile utilizzare .ix .

Come @Jeff commenti:

Questa è un'espressione di assegnazione (vedi 'advanced indexing with ix' section of the docs) e non restituisce nulla (anche se ci sono espressioni di assegnamento che facciamo cose di ritorno, per esempio .at e .iat).

df.loc[rows,columns]can può restituire una vista, ma di solito è una copia. Confuso, ma fatto per l'efficienza.

Bottom line: usoix, loc, ilocper impostare(come sopra), e non modificano copie.

Vedere la sezione 'view versus copy' dei documenti.

+0

Viene visualizzato un errore di attributo per df.loc. Presumo che questo è nuovo in panda 0.11. C'era un equivalente prima, o è per questo che ho bisogno di aggiornare i panda ogni altro mese? – Noah

+0

Inoltre, descrive da qualche parte nei documenti che questa è una vista, non una copia? Vedi http://pandas.pydata.org/pandas-docs/dev/indexing.html#indexing-view-versus-copy – Noah

+0

Sicuramente i documenti devono estendere di più quando è una vista o una copia, ho detto che aggiungerei alcuni documenti io stesso in passato (ho solo bisogno di elaborare tutti i dettagli), creerò un problema github per far rotolare la palla ... –