2017-10-19 8 views
0

J'ai découvert un bogue très subtil dans mon code. Je supprime fréquemment des lignes d'une base de données dans mon analyse. Parce que cela laissera des lacunes dans l'index, je tente de mettre fin à toutes les fonctions en remettant à zéro l'index à la fin avecQuand réinitialiser l'index? loc vs iloc pour les lacunes dans l'index? Les meilleures pratiques?

df0 = df0.reset_index (drop = True) 

Alors je continue dans la fonction suivante avec

for row in xrange (df0.shape [0]): 
    print df0.loc [row] 
    print df0.iloc [row] 

Cependant, si je ne réinitialiser l'index correctement, la première ligne peut avoir un index de 192. L'index de 192 n'est pas le même que le numéro de ligne de 0. Cela conduit au problème que df0.loc [ligne] accède à la ligne avec l'index 0, et df0.iloc [row] accède à la ligne avec l'index 192. Cela a provoqué un bug très étrange, en ce sens que j'essaye de mettre à jour la ligne 0, mais l'index 192 est mis à jour à la place. Ou vice versa.

Mais en réalité, je n'utilise aucune fonction df0.loc() ou df0.iloc() car elles sont trop lentes. Mon code est criblé de fonctions df0.get_value (...) et df0.set_value (...) car ce sont les fonctions les plus rapides lors de l'accès aux valeurs.

Et il semble que certaines fonctions sont accessibles par index, et d'autres sont accessibles par des numéros de ligne? Je suis confus. Quelqu'un peut-il m'expliquer? Quelles sont les meilleures pratiques? Certaines fonctions utilisent-elles l'index pour accéder aux valeurs, tandis que d'autres utilisent des numéros de lignes? Ai-je mal compris quelque chose? Dois-je toujours reset_index() aussi souvent que je peux? Ou ne fais jamais ça?

EDIT: Pour récapituler: Je fusionne manuellement certaines lignes dans les fonctions afin qu'il y ait des espaces dans les indications. Dans d'autres fonctions, je parcoure chaque rangée et fais des calculs. Cependant, si j'ai réinitialisé l'index, j'obtiens d'autres résultats de calcul que si je ne réinitialise pas l'index. Pourquoi? C'est mon problème.

+0

iloc devrait fonctionner quelles que soient les étiquettes d'index. Iloc (emplacement entier) récupérera les lignes en fonction de leur emplacement d'entier dans l'index. –

Répondre

1

.loc[] examine l'index étiquettes, qui peut être ou non une valeur entière.

  • Si votre index est [0, 1, 3] (un indice entier non séquentiel), .loc[2] ne trouverez rien, parce qu'il n'y a pas d'étiquette d'index 2.
  • De même, si votre index est ['a', 'b', 'c'] (un index non-entier), .loc[2] s'affichera vide.

.iloc[] regarde index positions, qui seront toujours une valeur entière.

  • Si votre index est [0, 1, 3], .loc[2] retournera la ligne correspondant à 3.
  • Si votre index est ['a', 'b', 'c'], .loc[2] renverra la ligne correspondant à 'c'.

Ce n'est pas un bogue, c'est la façon dont ces indexeurs sont conçus. L'adéquation à votre objectif dépend de la structure de vos données et de ce que vous essayez d'accomplir. Il est difficile de faire une recommandation sans en savoir plus.

Cela dit, il semble que votre code devienne plutôt épineux.Avoir à effectuer reset_index() dans un tas d'endroits différents et garder une trace constante de la ligne que vous essayez de mettre à jour suggèrent que vous ne pouvez pas profiter de la capacité de Pandas à effectuer des calculs vectoriels sur plusieurs lignes et colonnes à la fois. Peut-être que la tâche que vous voulez accomplir rend cela inévitable. Mais il est utile de prendre le temps d'examiner si vous ne pouvez pas vectoriser ce que vous faites, de sorte que vous puissiez l'appliquer à l'ensemble de la base de données ou à un sous-ensemble de la base de données plutôt que sur des cellules individuelles.

+0

Merci pour votre réponse. Je sais ce que vous venez d'expliquer, que loc() regarde les étiquettes, et iloc regarde les indices. Je ne peux pas vectoriser le code, j'ai besoin de regarder chaque cellule et de faire des calculs compliqués en fonction de beaucoup d'autres conditions. Je fusionne fréquemment plusieurs lignes en une seule via des conditions compliquées, puis je garde une trace des lignes que j'ai fusionnées et les supprime à la fin de la fonction. Mais alors l'index devient foiré, donc je dois le réinitialiser. Tous mes indices sont les numéros par défaut, je n'ai pas changé d'indication dans une autre colonne que la colonne d'index normale. Je suis confus. –

+0

Je pense que j'ai mal compris votre problème. Si vous savez que '.iloc' et' .loc' donnent des résultats différents et pourquoi, alors vous savez pourquoi, dans vos mots "si j'ai réinitialisé l'index, j'obtiens d'autres résultats de calcul que si je ne réinitialise pas l'index". Peut-être que vous pouvez être plus précis sur le problème que vous rencontrez et comment les résultats que vous attendez diffèrent de ceux que vous obtenez. – ASGM