Cosa significa `ValueError: impossibile reindicizzare da un asse duplicato`?


254

Ricevo un ValueError: cannot reindex from a duplicate axisquando sto cercando di impostare un indice su un determinato valore. Ho provato a riprodurlo con un semplice esempio, ma non ci sono riuscito.

Ecco la mia sessione all'interno di ipdbtrace. Ho un DataFrame con indice di stringa e colonne intere, valori float. Tuttavia, quando provo a creare un sumindice per la somma di tutte le colonne, ricevo un ValueError: cannot reindex from a duplicate axiserrore. Ho creato un piccolo DataFrame con le stesse caratteristiche, ma non sono riuscito a riprodurre il problema, cosa potrei perdere?

Non capisco davvero cosa ValueError: cannot reindex from a duplicate axissignifichi, cosa significa questo messaggio di errore? Forse questo mi aiuterà a diagnosticare il problema, e questa è la parte più responsabile della mia domanda.

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

Ecco l'errore:

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

Ho provato a riprodurlo con un semplice esempio, ma non ci sono riuscito

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

1
C'è qualche possibilità che tu abbia offuscato i nomi delle colonne reali della tua matrice di affinità? (ovvero ha sostituito i valori reali con qualcos'altro per nascondere le informazioni sensibili)
Korem

@Korem, non penso che sia vero, ma anche se questo è vero, perché questo causerebbe l'errore sopra?
Akavall,

2
Di solito vedo questo quando l'indice assegnato a ha valori duplicati. Dato che nel tuo caso stai assegnando una riga, mi aspettavo un duplicato nei nomi delle colonne. Ecco perché ho chiesto.
Korem,

@Korem, In effetti i miei dati reali avevano valori di indice duplicati e sono stato in grado di riprodurre l'errore nel piccolo esempio quando erano presenti valori di indice duplicati. Hai risposto completamente alla mia domanda. Grazie. Ti dispiace metterlo come risposta?
Akavall,

Risposte:


170

Questo errore di solito aumenta quando si unisce / si assegna a una colonna quando l'indice ha valori duplicati. Dato che stai assegnando a una riga, sospetto che ci sia un valore duplicato in affinity_matrix.columns, forse non mostrato nella tua domanda.


20
Per essere più precisi, nel mio caso c'era un valore duplicato affinity_matrix.index, ma penso che questo sia lo stesso concetto.
Akavall,

24
Per quelli che verranno in seguito, indexsignifica entrambi rowe column names, trascorsi 20 minuti sull'indice di riga ma alla fine ho ottenuto nomi di colonne duplicati che hanno causato questo errore.
Jason Goal,

Per aggiungere a questo, ho riscontrato questo errore quando ho provato a reindicizzare un frame di dati in un elenco di colonne. Stranamente, il mio duplicato era nel mio frame di dati originale, quindi assicurati di controllare entrambi!
m8_6

163

Come altri hanno già detto, probabilmente hai valori duplicati nell'indice originale. Per trovarli fai questo:

df[df.index.duplicated()]


39
Per rimuovere le righe con indici duplicati, utilizzare:df = df[~df.index.duplicated()]
tuomastik

4
Per DatetimeIndexdataframes ED, è possibile resamplela frequenza desiderata e poi prendere .first(), .mean()e così via
BallpointBen

28

Gli indici con valori duplicati sorgono spesso se si crea un DataFrame concatenando altri DataFrame. Se non ti interessa conservare i valori del tuo indice e vuoi che siano valori univoci, quando concateni i dati, imposta ignore_index=True.

In alternativa, per sovrascrivere il tuo indice corrente con uno nuovo, invece di utilizzare df.reindex(), imposta:

df.index = new_index

8
Ho usato ignore_index = True per far funzionare il mio codice con i frame di dati concatenati
Gabi Lee

In effetti, ignore_index=Falseè l'impostazione predefinita; se usare l'opzione significa cambiare appendil comportamento, lo sarà perché lo hai impostato su True.
Jeffrey Benjamin Brown,

17

Per le persone che stanno ancora lottando con questo errore, può accadere anche se si crea accidentalmente una colonna duplicata con lo stesso nome. Rimuovi le colonne duplicate in questo modo:

df = df.loc[:,~df.columns.duplicated()]

12

Basta saltare l'errore usando .valuesalla fine.

affinity_matrix.loc['sums'] = affinity_matrix.sum(axis=0).values

Questo è esattamente quello di cui avevo bisogno! Stavo solo cercando di creare una nuova colonna, ma avevo un indice con duplicati. Usando ha .valuesfatto il trucco
Paul Wildenhain il

8

Mi sono imbattuto in questo errore oggi quando volevo aggiungere una nuova colonna come questa

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

Volevo elaborare la REMARKcolonna di df_temprestituire 1 o 0. Tuttavia ho digitato la variabile errata con df. E ha restituito un errore del genere:

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

Come puoi vedere, dovrebbe essere il codice giusto

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

Perché dfe df_temphanno un numero diverso di righe. Quindi è tornato ValueError: cannot reindex from a duplicate axis.

Spero che tu possa capirlo e la mia risposta può aiutare altre persone a eseguire il debug del loro codice.


4

Nel mio caso, questo errore è apparso non a causa di valori duplicati, ma perché ho tentato di unire una Serie più breve a un Dataframe: entrambi avevano lo stesso indice, ma la Serie aveva meno righe (mancano le prime). Quanto segue ha funzionato per i miei scopi:

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

Grazie! Mi ero abituato a filtrare e in seguito unire DataFrames e Series in questo modo: df_larger_dataframe['values'] = df_filtered_dataframe['filtered_values'] e ultimamente non ha funzionato su TimeSeries - il tuo codice l'ha risolto!
tw0000,

2

Ho perso un paio d'ore sullo stesso problema. Nel mio caso, ho dovuto ripristinare reset_index () di un frame di dati prima di utilizzare la funzione apply. Prima di unire o cercare un altro set di dati indicizzato, è necessario reimpostare l'indice poiché 1 set di dati può avere solo 1 indice.


2

Correzione semplice che ha funzionato per me

Esegui df.reset_index(inplace=True)prima di raggruppare.

Grazie a questo commento github per la soluzione.


@Chris_vr rimuovere la parte inplace se si desidera che restituisca il frame di dati
Connor
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.