Il modo giusto per invertire pandas.DataFrame?


117

Ecco il mio codice:

import pandas as pd

data = pd.DataFrame({'Odd':[1,3,5,6,7,9], 'Even':[0,2,4,6,8,10]})

for i in reversed(data):
    print(data['Odd'], data['Even'])

Quando eseguo questo codice, ottengo il seguente errore:

Traceback (most recent call last):
  File "C:\Python33\lib\site-packages\pandas\core\generic.py", line 665, in _get_item_cache
    return cache[item]
KeyError: 5

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "C:\Users\*****\Documents\******\********\****.py", line 5, in <module>
    for i in reversed(data):
  File "C:\Python33\lib\site-packages\pandas\core\frame.py", line 2003, in __getitem__
    return self._get_item_cache(key)
  File "C:\Python33\lib\site-packages\pandas\core\generic.py", line 667, in _get_item_cache
    values = self._data.get(item)
  File "C:\Python33\lib\site-packages\pandas\core\internals.py", line 1656, in get
    _, block = self._find_block(item)
  File "C:\Python33\lib\site-packages\pandas\core\internals.py", line 1936, in _find_block
    self._check_have(item)
  File "C:\Python33\lib\site-packages\pandas\core\internals.py", line 1943, in _check_have
    raise KeyError('no item named %s' % com.pprint_thing(item))
KeyError: 'no item named 5'

Perché ricevo questo errore?
Come posso ripararlo?
Qual è il modo giusto per invertire pandas.DataFrame?


3
Che output stai cercando? "One"non è una colonna in data, e non so se Twoè una variabile o un errore di battitura per "Two", che inoltre non è una colonna. Stai solo cercando di invertire l'ordine delle colonne?
DSM

Volevi dire data[["Odd", "Even"]], o più in generale data[data.columns[::-1]],?
Fred Foo

1
Non hai ancora fornito un esempio dell'output che desideri. So come aggirare il fatto che il fatto reversed(data)non funziona, ma non so perché vorresti stampare l'intero Odde le Evencolonne una volta per ogni colonna nel frame, che è quello che farebbe il tuo codice se lo usassi reversed(list(data)).
DSM

Voglio iniziare il ciclo for dalla fine del mio dataFrame
Michael

2
Allora penso che la tua domanda sia una duplicazione di questa , e tu vuoi qualcosa di simile for i, row in data[::-1].iterrows(): print row["Odd"], row["Even"]. Per favore fornisci sempre degli esempi nella tua domanda del risultato che ti aspetti; rende la vita molto più facile a tutti.
DSM

Risposte:


246
data.reindex(index=data.index[::-1])

o semplicemente:

data.iloc[::-1]

invertirà il frame dei dati, se vuoi avere un forloop che va dal basso verso l'alto puoi fare:

for idx in reversed(data.index):
    print(idx, data.loc[idx, 'Even'], data.loc[idx, 'Odd'])

o

for idx in reversed(data.index):
    print(idx, data.Even[idx], data.Odd[idx])

Hai trovato un errore perché reversedprimi inviti data.__len__()che restituisce 6. Poi si cerca di chiamare data[j - 1]per ja range(6, 0, -1), e la prima chiamata sarebbe data[5]; ma in pandas dataframe data[5]significa colonna 5 e non c'è colonna 5 quindi genererà un'eccezione. (vedi documenti )


se hai problemi puoi provare questo:for index, row in df.iloc[::-1].iterrows():
kristian

qualche modo per farlo sul posto ? equivalente di ipoteticodata.reindex(index=data.index[::-1], inplace=True)
NeuronQ

3
Può fare data = data.reindex(index=data.index[::-1])quindi data.reset_index(inplace=True, drop=True)e verrà ripristinato in posizione.
Matts

4
È df = df[::-1]una soluzione pitonica e valida?
tommy.carstensen

@ tommy.carstensen sì, e dovrebbe essere la risposta in alto
rosstripi

65

Puoi invertire le righe in un modo ancora più semplice:

df[::-1]

3
Mi piace definire il mio reverse()metodo con pd.Series.reverse = pd.DataFrame.reverse = lambda self: self[::-1]perché sembra più bello quando concatenano metodi, ad es df.reverse().iterrows().
Ben Mares

5

Nessuna delle risposte esistenti ripristina l'indice dopo aver invertito il dataframe.

Per questo, procedi come segue:

 data[::-1].reset_index()

Ecco una funzione di utilità che rimuove anche la vecchia colonna dell'indice, come da commento di @ Tim:

def reset_my_index(df):
  res = df[::-1].reset_index(drop=True)
  return(res)

Passa semplicemente il tuo dataframe nella funzione


1
Probabilmente vorresti avere drop=True, ie data[::-1].reset_index(drop=True):, altrimenti il ​​vecchio indice verrà aggiunto come colonna sul DataFrame.
Tim,

Perché dovresti farlo?
endolith

@endolith Alcune biblioteche si aspettano che il frame di dati venga indicizzato. Ad esempio, alcune librerie di previsioni di serie temporali si aspettano un frame indicizzato come input in modo che possa modellare una serie temporale pur rimanendo indipendente dal passaggio temporale (giorno, mese, anno, ecc.). Quindi potresti lavorare con un data frame, fare una trasformazione su di esso, il che rovina l'indicizzazione. È comune reindicizzare così la cornice.
Cybernetic

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.