Bonne façon d'inverser pandas.DataFrame?

117

Voici mon code:

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

Lorsque j'exécute ce code, j'obtiens l'erreur suivante:

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'

Pourquoi ai-je cette erreur?
Comment puis-je résoudre ce problème?
Quelle est la bonne façon de faire marche arrière pandas.DataFrame?

Michael
la source
3
Quelle sortie recherchez-vous? "One"n'est pas une colonne dans data, et je ne sais pas si Twoest une variable ou une faute de frappe pour "Two", qui n'est pas non plus une colonne. Cherchez-vous simplement à inverser l'ordre des colonnes?
DSM
Vouliez-vous dire data[["Odd", "Even"]], ou plus généralement data[data.columns[::-1]],?
Fred Foo
1
Vous n'avez toujours pas donné d'exemple de la sortie souhaitée. Je sais comment contourner le fait reversed(data)ne fonctionne pas, mais je ne sais pas pourquoi vous voudriez imprimer le tout Oddet les Evencolonnes une fois pour chaque colonne du cadre, ce que votre code ferait si vous l'utilisiez reversed(list(data)).
DSM
Je veux commencer pour la boucle à partir de la fin de mon dataFrame
Michael
2
Ensuite, je pense que votre question est une dupe de celle-ci , et vous voulez quelque chose comme for i, row in data[::-1].iterrows(): print row["Odd"], row["Even"]. Veuillez toujours donner des exemples dans votre question de la sortie que vous attendez; cela rend la vie beaucoup plus facile pour tout le monde.
DSM

Réponses:

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

ou simplement:

data.iloc[::-1]

va inverser votre trame de données, si vous voulez avoir une forboucle qui va de bas en haut, vous pouvez faire:

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

Vous obtenez une erreur parce que le reversedpremier appelle data.__len__()qui renvoie 6. Ensuite, il essaie d'appeler data[j - 1]pour jin range(6, 0, -1), et le premier appel serait data[5]; mais dans pandas dataframe data[5]signifie la colonne 5, et il n'y a pas de colonne 5 donc il lancera une exception. (voir docs )

behzad.nouri
la source
si vous rencontrez des problèmes, vous pouvez essayer ceci:for index, row in df.iloc[::-1].iterrows():
kristian
un moyen de le faire en place ? équivalent d'hypothétiquedata.reindex(index=data.index[::-1], inplace=True)
NeuronQ
3
Peut faire data = data.reindex(index=data.index[::-1])alors data.reset_index(inplace=True, drop=True)et il sera remis en place.
Matts
4
Une df = df[::-1]solution pythonique et valable?
tommy.carstensen
@ tommy.carstensen oui, et cela devrait être la meilleure réponse
rosstripi
65

Vous pouvez inverser les lignes de manière encore plus simple:

df[::-1]
user1951
la source
3
J'aime définir ma propre reverse()méthode avec pd.Series.reverse = pd.DataFrame.reverse = lambda self: self[::-1]parce qu'elle est plus jolie lors du chaînage de méthodes, par exemple df.reverse().iterrows().
Ben Mares
5

Aucune des réponses existantes ne réinitialise l'index après l'inversion de la trame de données.

Pour cela, procédez comme suit:

 data[::-1].reset_index()

Voici une fonction utilitaire qui supprime également l'ancienne colonne d'index, selon le commentaire de @ Tim:

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

Passez simplement votre dataframe dans la fonction

Cybernétique
la source
1
Vous souhaitez probablement avoir drop=True, c'est-à-dire data[::-1].reset_index(drop=True):, sinon l'ancien index sera ajouté en tant que colonne sur le DataFrame.
Tim
Pourquoi voudriez-vous faire ça?
endolith
@endolith Certaines bibliothèques s'attendent à ce que le bloc de données soit indexé. Par exemple, certaines bibliothèques de prévisions de séries temporelles attendent une image indexée en entrée afin de pouvoir modéliser une série chronologique tout en restant indépendante du pas de temps (jour, mois, année, etc.). Vous travaillez peut-être avec un bloc de données, effectuez une transformation dessus, ce qui gâche l'indexation. Il est courant de réindexer ainsi le cadre.
Cybernetic
1

Cela marche:

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