Forma correcta de revertir pandas.DataFrame?

117

Aquí está mi código:

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'])

Cuando ejecuto este código, aparece el siguiente error:

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'

¿Por qué recibo este error?
¿Cómo puedo arreglar eso?
¿Cuál es la forma correcta de revertir pandas.DataFrame?

Miguel
fuente
3
¿Qué salida estás buscando? "One"no es una columna data, y no sé si Twoes una variable o un error tipográfico "Two", que tampoco es una columna. ¿Está buscando invertir el orden de las columnas?
DSM
¿Quiso decir data[["Odd", "Even"]], o más en general data[data.columns[::-1]],?
Fred Foo
1
Todavía no ha dado un ejemplo de la salida que desea. Sé cómo evitar el hecho de reversed(data)que no funciona, pero no sé por qué querría imprimir el conjunto Oddy las Evencolumnas una vez para cada columna en el marco, que es lo que haría su código si lo usara reversed(list(data)).
DSM
Quiero comenzar el bucle desde el final de mi dataFrame
Michael
2
Entonces creo que tu pregunta es un duplicado de esta , y quieres algo como for i, row in data[::-1].iterrows(): print row["Odd"], row["Even"]. En su pregunta, proporcione siempre ejemplos del resultado que espera; hace la vida mucho más fácil para todos.
DSM

Respuestas:

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

o simplemente:

data.iloc[::-1]

invertirá su marco de datos, si desea tener un forbucle que vaya de abajo hacia arriba, puede hacer:

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])

Que está recibiendo un error porque reversedprimeras llamadas data.__len__()que devuelve 6. Finalmente se trata de llamar data[j - 1]para jen range(6, 0, -1), y la primera llamada sería data[5]; pero en pandas dataframe data[5]significa columna 5, y no hay columna 5, por lo que arrojará una excepción. (ver documentos )

behzad.nouri
fuente
si tiene problemas, puede probar esto:for index, row in df.iloc[::-1].iterrows():
kristian
alguna forma de hacerlo en su lugar ? equivalente de hipotéticodata.reindex(index=data.index[::-1], inplace=True)
NeuronQ
3
Puede hacer data = data.reindex(index=data.index[::-1])a continuación, data.reset_index(inplace=True, drop=True)y se restablecerá en su lugar.
Matts
4
¿Es df = df[::-1]una solución pitónica y válida?
tommy.carstensen
@ tommy.carstensen sí, y debería ser la respuesta principal
rosstripi
65

Puede invertir las filas de una manera aún más simple:

df[::-1]
user1951
fuente
3
Me gusta definir mi propio reverse()método con pd.Series.reverse = pd.DataFrame.reverse = lambda self: self[::-1]porque se ve mejor al encadenar métodos, por ejemplo df.reverse().iterrows().
Ben Mares
5

Ninguna de las respuestas existentes restablece el índice después de invertir el marco de datos.

Para ello, haga lo siguiente:

 data[::-1].reset_index()

Aquí hay una función de utilidad que también elimina la columna de índice anterior, según el comentario de @ Tim:

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

Simplemente pase su marco de datos a la función

Cibernético
fuente
1
Probablemente desee tener drop=True, es decir:, de lo data[::-1].reset_index(drop=True)contrario, el índice anterior se agregará como una columna en el DataFrame.
Tim
Por qué querrías hacer esto?
endolito
@endolith Algunas bibliotecas esperan que el marco de datos esté indexado. Por ejemplo, algunas bibliotecas de predicción de series de tiempo esperan un marco indexado como entrada para que pueda modelar una serie de tiempo sin dejar de ser independiente del paso de tiempo (día, mes, año, etc.). Entonces, puede estar trabajando con un marco de datos, hacer una transformación en él, lo que arruina la indexación. Por lo tanto, es común volver a indexar el marco.
Cybernetic
1

Esto funciona:

    for i,r in data[::-1].iterrows():
        print(r['Odd'], r['Even'])
Michael Styrk
fuente