Maneira certa de reverter pandas.DataFrame?

117

Aqui está o meu 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'])

Quando executo este código, recebo o seguinte erro:

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 que estou recebendo este erro?
Como posso consertar isso?
Qual é a maneira certa de reverter pandas.DataFrame?

Michael
fonte
3
Qual saída você está procurando? "One"não é uma coluna em data, e não sei se Twoé uma variável ou um erro de digitação para "Two", que também não é uma coluna. Você está apenas tentando inverter a ordem das colunas?
DSM
Você quis dizer data[["Odd", "Even"]], ou mais geralmente data[data.columns[::-1]],?
Fred Foo
1
Você ainda não deu um exemplo da saída que deseja. Eu sei como contornar o fato reversed(data)não funciona, mas não sei por que você deseja imprimir todas as colunas Odde Evenuma vez para cada coluna no quadro, que é o que seu código faria se você usasse reversed(list(data)).
DSM
Quero iniciar o loop for a partir do final do meu dataFrame
Michael
2
Então eu acho que sua pergunta é uma cópia desta , e você quer algo parecido for i, row in data[::-1].iterrows(): print row["Odd"], row["Even"]. Sempre dê exemplos em sua pergunta sobre a saída que você espera; torna a vida muito mais fácil para todos.
DSM

Respostas:

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

ou simplesmente:

data.iloc[::-1]

irá reverter seu quadro de dados, se você quiser ter um forloop que vai de baixo para cima, você pode fazer:

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

ou

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

Você está recebendo um erro porque reversedprimeiras chamadas data.__len__()que retorna 6. Em seguida, ele tenta chamar data[j - 1]para jnos range(6, 0, -1), e a primeira chamada seria data[5]; mas no pandas dataframe data[5]significa coluna 5, e não há coluna 5, portanto, ele lançará uma exceção. (ver docs )

behzad.nouri
fonte
se você estiver tendo problemas, pode tentar isto:for index, row in df.iloc[::-1].iterrows():
Cristão
alguma maneira de fazer isso no lugar ? equivalente de hipotéticodata.reindex(index=data.index[::-1], inplace=True)
NeuronQ
3
Pode fazer data = data.reindex(index=data.index[::-1])então data.reset_index(inplace=True, drop=True)e ele será reiniciado no lugar.
Matts de
4
É df = df[::-1]uma solução pitônica e válida?
tommy.carstensen
@ tommy.carstensen sim, e deve ser a resposta principal
rosstripi
66

Você pode inverter as linhas de uma maneira ainda mais simples:

df[::-1]
user1951
fonte
4
Gosto de definir meu próprio reverse()método com pd.Series.reverse = pd.DataFrame.reverse = lambda self: self[::-1]porque fica mais bonito ao encadear métodos, por exemplo df.reverse().iterrows().
Ben Mares
5

Nenhuma das respostas existentes redefine o índice após reverter o dataframe.

Para isso, faça o seguinte:

 data[::-1].reset_index()

Aqui está uma função de utilidade que também remove a coluna do índice antigo, de acordo com o comentário de @Tim:

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

Basta passar seu dataframe para a função

Cibernético
fonte
1
Você provavelmente deseja ter drop=True, ou seja data[::-1].reset_index(drop=True):, caso contrário, o índice antigo será adicionado como uma coluna no DataFrame.
Tim
Por que você quer fazer isso?
endolith
1
@endolith Algumas bibliotecas esperam que o quadro de dados seja indexado. Por exemplo, algumas bibliotecas de previsão de série temporal esperam um quadro indexado como entrada para que possa modelar uma série temporal enquanto permanece agnóstica em relação ao intervalo de tempo (dia, mês, ano, etc.). Portanto, você pode estar trabalhando com um quadro de dados, fazer uma transformação nele, o que atrapalha a indexação. É comum assim reindexar a moldura.
Cybernetic
1

Isso funciona:

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