Que signifie «ValueError: impossible de réindexer à partir d'un axe en double»?

254

J'obtiens un ValueError: cannot reindex from a duplicate axislorsque j'essaie de définir un index sur une certaine valeur. J'ai essayé de reproduire cela avec un exemple simple, mais je n'ai pas pu le faire.

Voici ma session à l'intérieur de ipdbtrace. J'ai un DataFrame avec un index de chaîne et des colonnes entières, des valeurs flottantes. Cependant, lorsque j'essaie de créer un sumindex pour la somme de toutes les colonnes, j'obtiens une ValueError: cannot reindex from a duplicate axiserreur. J'ai créé un petit DataFrame avec les mêmes caractéristiques, mais je n'ai pas pu reproduire le problème, que pourrais-je manquer?

Je ne comprends pas vraiment ce que ValueError: cannot reindex from a duplicate axissignifie, que signifie ce message d'erreur? Peut-être que cela m'aidera à diagnostiquer le problème, et c'est la partie la plus responsable de ma question.

ipdb> type(affinity_matrix)
<class 'pandas.core.frame.DataFrame'>
ipdb> affinity_matrix.shape
(333, 10)
ipdb> affinity_matrix.columns
Int64Index([9315684, 9315597, 9316591, 9320520, 9321163, 9320615, 9321187, 9319487, 9319467, 9320484], dtype='int64')
ipdb> affinity_matrix.index
Index([u'001', u'002', u'003', u'004', u'005', u'008', u'009', u'010', u'011', u'014', u'015', u'016', u'018', u'020', u'021', u'022', u'024', u'025', u'026', u'027', u'028', u'029', u'030', u'032', u'033', u'034', u'035', u'036', u'039', u'040', u'041', u'042', u'043', u'044', u'045', u'047', u'047', u'048', u'050', u'053', u'054', u'055', u'056', u'057', u'058', u'059', u'060', u'061', u'062', u'063', u'065', u'067', u'068', u'069', u'070', u'071', u'072', u'073', u'074', u'075', u'076', u'077', u'078', u'080', u'082', u'083', u'084', u'085', u'086', u'089', u'090', u'091', u'092', u'093', u'094', u'095', u'096', u'097', u'098', u'100', u'101', u'103', u'104', u'105', u'106', u'107', u'108', u'109', u'110', u'111', u'112', u'113', u'114', u'115', u'116', u'117', u'118', u'119', u'121', u'122', ...], dtype='object')

ipdb> affinity_matrix.values.dtype
dtype('float64')
ipdb> 'sums' in affinity_matrix.index
False

Voici l'erreur:

ipdb> affinity_matrix.loc['sums'] = affinity_matrix.sum(axis=0)
*** ValueError: cannot reindex from a duplicate axis

J'ai essayé de reproduire cela avec un exemple simple, mais j'ai échoué

In [32]: import pandas as pd

In [33]: import numpy as np

In [34]: a = np.arange(35).reshape(5,7)

In [35]: df = pd.DataFrame(a, ['x', 'y', 'u', 'z', 'w'], range(10, 17))

In [36]: df.values.dtype
Out[36]: dtype('int64')

In [37]: df.loc['sums'] = df.sum(axis=0)

In [38]: df
Out[38]: 
      10  11  12  13  14  15   16
x      0   1   2   3   4   5    6
y      7   8   9  10  11  12   13
u     14  15  16  17  18  19   20
z     21  22  23  24  25  26   27
w     28  29  30  31  32  33   34
sums  70  75  80  85  90  95  100
Akavall
la source
1
Y a-t-il une chance que vous obscurcissiez les vrais noms de colonne de votre matrice d'affinité? (ie a remplacé les valeurs réelles par quelque chose d'autre pour cacher les informations sensibles)
Korem
@ Korem, je ne pense pas que ce soit vrai, mais même si c'est vrai, pourquoi cela provoquerait-il l'erreur ci-dessus?
Akavall
2
Je vois généralement cela lorsque l'index attribué à a des valeurs en double. Étant donné que dans votre cas, vous attribuez une ligne, je m'attendais à un doublon dans les noms de colonne. C'est pourquoi j'ai demandé.
Korem
@Korem, En effet, mes données réelles avaient des valeurs d'index en double, et j'ai pu reproduire l'erreur dans le petit exemple lorsque des valeurs d'index en double étaient présentes. Vous avez pleinement répondu à ma question. Merci. Cela vous dérange de le mettre comme réponse?
Akavall

Réponses:

170

Cette erreur se produit généralement lorsque vous joignez / affectez à une colonne lorsque l'index a des valeurs en double. Puisque vous attribuez à une ligne, je soupçonne qu'il y a une valeur en double dans affinity_matrix.columns, peut-être pas montrée dans votre question.

Korem
la source
20
Pour être plus précis, dans mon cas, une valeur en double était présente affinity_matrix.index, mais je pense que c'est le même concept.
Akavall
24
Pour ceux qui viendront plus tard, cela indexsignifie les deux rowet column names, j'ai passé 20 minutes sur l'index des lignes, mais il s'est avéré que j'ai obtenu des noms de colonnes en double qui ont causé cette erreur.
Jason Goal
Pour ajouter à cela, je suis tombé sur cette erreur lorsque j'ai essayé de réindexer une trame de données sur une liste de colonnes. Curieusement, ma copie était dans ma trame de données d'origine, alors assurez-vous de vérifier les deux!
m8_
163

Comme d'autres l'ont dit, vous avez probablement des valeurs en double dans votre index d'origine. Pour les trouver, procédez comme suit:

df[df.index.duplicated()]

Matthieu
la source
39
Pour supprimer des lignes avec des index dupliqués, utilisez:df = df[~df.index.duplicated()]
tuomastik
4
Pour DatetimeIndexdataframes ées, vous pouvez resampleà la fréquence désirée, puis prendre .first(), .mean()etc.
BallpointBen
28

Les indices avec des valeurs en double surviennent souvent si vous créez un DataFrame en concaténant d'autres DataFrames. SI vous ne vous souciez pas de conserver les valeurs de votre index et que vous souhaitez qu'elles soient des valeurs uniques, lorsque vous concaténez les données, définissez ignore_index=True.

Alternativement, pour remplacer votre index actuel par un nouveau, au lieu d'utiliser df.reindex(), définissez:

df.index = new_index
Rebeku
la source
8
J'ai utilisé ignore_index = True pour que mon code fonctionne avec des trames de données concaténées
Gabi Lee
En effet, ignore_index=Falsec'est la valeur par défaut; si l 'utilisation de l' option consiste à changer appendle comportement de, cela devra être parce que vous la définissez sur True.
Jeffrey Benjamin Brown
17

Pour les personnes qui ont toujours des problèmes avec cette erreur, cela peut également arriver si vous créez accidentellement une colonne en double avec le même nom. Supprimez les colonnes en double comme ceci:

df = df.loc[:,~df.columns.duplicated()]
Fourchelangue
la source
12

Ignorez simplement l'erreur en utilisant .valuesà la fin.

affinity_matrix.loc['sums'] = affinity_matrix.sum(axis=0).values
Hadij
la source
C'est exactement ce dont j'avais besoin! J'essaye juste de créer une nouvelle colonne, mais j'avais un index avec des doublons dedans. L'utilisation a .valuesfait l'affaire
Paul Wildenhain
8

Je suis tombé sur cette erreur aujourd'hui quand je voulais ajouter une nouvelle colonne comme celle-ci

df_temp['REMARK_TYPE'] = df.REMARK.apply(lambda v: 1 if str(v)!='nan' else 0)

Je voulais traiter la REMARKcolonne de df_temppour retourner 1 ou 0. Cependant, j'ai tapé une variable incorrecte avec df. Et il a renvoyé une erreur comme celle-ci:

----> 1 df_temp['REMARK_TYPE'] = df.REMARK.apply(lambda v: 1 if str(v)!='nan' else 0)

/usr/lib64/python2.7/site-packages/pandas/core/frame.pyc in __setitem__(self, key, value)
   2417         else:
   2418             # set column
-> 2419             self._set_item(key, value)
   2420 
   2421     def _setitem_slice(self, key, value):

/usr/lib64/python2.7/site-packages/pandas/core/frame.pyc in _set_item(self, key, value)
   2483 
   2484         self._ensure_valid_index(value)
-> 2485         value = self._sanitize_column(key, value)
   2486         NDFrame._set_item(self, key, value)
   2487 

/usr/lib64/python2.7/site-packages/pandas/core/frame.pyc in _sanitize_column(self, key, value, broadcast)
   2633 
   2634         if isinstance(value, Series):
-> 2635             value = reindexer(value)
   2636 
   2637         elif isinstance(value, DataFrame):

/usr/lib64/python2.7/site-packages/pandas/core/frame.pyc in reindexer(value)
   2625                     # duplicate axis
   2626                     if not value.index.is_unique:
-> 2627                         raise e
   2628 
   2629                     # other

ValueError: cannot reindex from a duplicate axis

Comme vous pouvez le voir, le bon code doit être

df_temp['REMARK_TYPE'] = df_temp.REMARK.apply(lambda v: 1 if str(v)!='nan' else 0)

Parce que dfet df_tempont un nombre différent de lignes. Il est donc revenu ValueError: cannot reindex from a duplicate axis.

J'espère que vous pourrez le comprendre et ma réponse pourra aider d'autres personnes à déboguer leur code.

GoingMyWay
la source
4

Dans mon cas, cette erreur est apparue non pas à cause de valeurs en double, mais parce que j'ai essayé de joindre une série plus courte à un Dataframe: les deux avaient le même index, mais la série avait moins de lignes (il manque les quelques premières). Les éléments suivants ont fonctionné à mes fins:

df.head()
                          SensA
date                           
2018-04-03 13:54:47.274   -0.45
2018-04-03 13:55:46.484   -0.42
2018-04-03 13:56:56.235   -0.37
2018-04-03 13:57:57.207   -0.34
2018-04-03 13:59:34.636   -0.33

series.head()
date
2018-04-03 14:09:36.577    62.2
2018-04-03 14:10:28.138    63.5
2018-04-03 14:11:27.400    63.1
2018-04-03 14:12:39.623    62.6
2018-04-03 14:13:27.310    62.5
Name: SensA_rrT, dtype: float64

df = series.to_frame().combine_first(df)

df.head(10)
                          SensA  SensA_rrT
date                           
2018-04-03 13:54:47.274   -0.45        NaN
2018-04-03 13:55:46.484   -0.42        NaN
2018-04-03 13:56:56.235   -0.37        NaN
2018-04-03 13:57:57.207   -0.34        NaN
2018-04-03 13:59:34.636   -0.33        NaN
2018-04-03 14:00:34.565   -0.33        NaN
2018-04-03 14:01:19.994   -0.37        NaN
2018-04-03 14:02:29.636   -0.34        NaN
2018-04-03 14:03:31.599   -0.32        NaN
2018-04-03 14:04:30.779   -0.33        NaN
2018-04-03 14:05:31.733   -0.35        NaN
2018-04-03 14:06:33.290   -0.38        NaN
2018-04-03 14:07:37.459   -0.39        NaN
2018-04-03 14:08:36.361   -0.36        NaN
2018-04-03 14:09:36.577   -0.37       62.2
tehfink
la source
Je vous remercie! Je m'étais habitué au filtrage et plus tard à la fusion des DataFrames et des séries comme ça: df_larger_dataframe['values'] = df_filtered_dataframe['filtered_values'] et cela n'a pas fonctionné récemment sur TimeSeries - votre code l'a résolu!
tw0000
2

J'ai perdu quelques heures sur le même sujet. Dans mon cas, j'ai dû réinitialiser_index () d'une trame de données avant d'utiliser la fonction apply. Avant de fusionner ou de rechercher un autre ensemble de données indexé, vous devez réinitialiser l'index car 1 ensemble de données ne peut avoir qu'un seul index.

rishi jain
la source
2

Solution simple qui a fonctionné pour moi

Exécutez df.reset_index(inplace=True)avant de regrouper.

Merci à ce commentaire github pour la solution.

Connor
la source
@Chris_vr supprimez la partie interne si vous souhaitez qu'elle renvoie la trame de données
Connor