Was bedeutet "ValueError: Kann nicht von einer doppelten Achse neu indizieren"?

254

Ich erhalte eine, ValueError: cannot reindex from a duplicate axiswenn ich versuche, einen Index auf einen bestimmten Wert zu setzen. Ich habe versucht, dies mit einem einfachen Beispiel zu reproduzieren, aber ich konnte es nicht tun.

Hier ist meine Sitzung innerhalb der ipdbSpur. Ich habe einen DataFrame mit String-Index und Integer-Spalten, Float-Werte. Wenn ich jedoch versuche, einen sumIndex für die Summe aller Spalten zu erstellen , wird eine ValueError: cannot reindex from a duplicate axisFehlermeldung angezeigt. Ich habe einen kleinen DataFrame mit denselben Eigenschaften erstellt, konnte das Problem jedoch nicht reproduzieren. Was könnte mir fehlen?

Ich verstehe nicht wirklich, was ValueError: cannot reindex from a duplicate axisbedeutet, was bedeutet diese Fehlermeldung? Vielleicht hilft mir das bei der Diagnose des Problems, und dies ist der am besten zu beantwortende Teil meiner Frage.

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

Hier ist der Fehler:

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

Ich habe versucht, dies anhand eines einfachen Beispiels zu reproduzieren, bin aber gescheitert

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
quelle
1
Besteht die Möglichkeit, dass Sie die tatsächlichen Spaltennamen Ihrer Affinitätsmatrix verschleiert haben? (dh die realen Werte durch etwas anderes ersetzt, um vertrauliche Informationen zu verbergen)
Korem
@Korem, ich denke nicht, dass dies wahr ist, aber selbst wenn dies wahr ist, warum würde dies den obigen Fehler verursachen?
Akavall
2
Ich sehe dies normalerweise, wenn der zugewiesene Index doppelte Werte hat. Da Sie in Ihrem Fall eine Zeile zuweisen, habe ich ein Duplikat in den Spaltennamen erwartet. Darum habe ich gefragt.
Korem
@Korem, In der Tat hatten meine tatsächlichen Daten doppelte Indexwerte, und ich konnte den Fehler in dem kleinen Beispiel reproduzieren, wenn doppelte Indexwerte vorhanden waren. Sie haben meine Frage vollständig beantwortet. Danke. Stört es Sie, es als Antwort zu geben?
Akavall

Antworten:

170

Dieser Fehler tritt normalerweise auf, wenn Sie einer Spalte beitreten / zuweisen, wenn der Index doppelte Werte enthält. Da Sie einer Zeile zuweisen, vermute ich, dass ein doppelter Wert in vorhanden affinity_matrix.columnsist, der in Ihrer Frage möglicherweise nicht angezeigt wird.

Korem
quelle
20
Genauer gesagt war in meinem Fall ein doppelter Wert vorhanden affinity_matrix.index, aber ich denke, dies ist das gleiche Konzept.
Akavall
24
Für diejenigen, die später darauf zurückkommen, indexbedeutet dies beides rowund column namesverbrachte 20 Minuten mit dem Zeilenindex, stellte sich jedoch heraus, dass ich doppelte Spaltennamen erhalten habe, die diesen Fehler verursacht haben.
Jason Goal
Um dies hinzuzufügen, bin ich auf diesen Fehler gestoßen, als ich versucht habe, einen Datenrahmen in einer Liste von Spalten neu zu indizieren. Seltsamerweise befand sich mein Duplikat in meinem ursprünglichen Datenrahmen. Überprüfen Sie also unbedingt beide!
m8_
163

Wie andere gesagt haben, haben Sie wahrscheinlich doppelte Werte in Ihrem ursprünglichen Index. Um sie zu finden, gehen Sie wie folgt vor:

df[df.index.duplicated()]

Matthew
quelle
39
Um Zeilen mit doppelten Indizes zu entfernen, verwenden Sie:df = df[~df.index.duplicated()]
Tuomastik
4
Für DatetimeIndexed Datenrahmen, können Sie resampleauf die gewünschte Frequenz und dann nehmen .first(), .mean()usw.
BallpointBen
28

Indizes mit doppelten Werten treten häufig auf, wenn Sie einen DataFrame durch Verketten anderer DataFrames erstellen. WENN Sie sich nicht darum kümmern, die Werte Ihres Index beizubehalten, und Sie möchten, dass sie eindeutige Werte sind, wenn Sie die Daten verketten, setzen Sie sie ignore_index=True.

Alternativ können Sie Folgendes df.reindex()festlegen , um Ihren aktuellen Index mit einem neuen zu überschreiben, anstatt ihn zu verwenden :

df.index = new_index
Rebeku
quelle
8
Ich habe ignore_index = True verwendet, um meinen Code für die Arbeit mit verketteten Datenrahmen zu verwenden
Gabi Lee
In ignore_index=Falseder Tat ist die Standardeinstellung; Wenn Sie die Option verwenden, um appenddas Verhalten überhaupt zu ändern , muss dies daran liegen, dass Sie es festgelegt haben True.
Jeffrey Benjamin Brown
17

Bei Personen, die immer noch mit diesem Fehler zu kämpfen haben, kann es auch vorkommen, dass Sie versehentlich eine doppelte Spalte mit demselben Namen erstellen. Entfernen Sie doppelte Spalten wie folgt:

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

Überspringen Sie einfach den Fehler mit .valuesam Ende.

affinity_matrix.loc['sums'] = affinity_matrix.sum(axis=0).values
Hadij
quelle
Das ist genau das, was ich brauchte! Ich habe nur versucht, eine neue Spalte zu erstellen, aber ich hatte einen Index mit Duplikaten. Mit .valueshat den Trick gemacht
Paul Wildenhain
8

Ich bin heute auf diesen Fehler gestoßen, als ich eine neue Spalte wie diese hinzufügen wollte

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

Ich wollte die REMARKSpalte von verarbeiten df_temp, um 1 oder 0 zurückzugeben. Allerdings habe ich eine falsche Variable mit eingegeben df. Und es gab Fehler wie folgt zurück:

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

Wie Sie sehen können, sollte der richtige Code sein

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

Weil dfund df_tempeine andere Anzahl von Zeilen haben. Also kehrte es zurück ValueError: cannot reindex from a duplicate axis.

Ich hoffe, Sie können es verstehen und meine Antwort kann anderen Menschen helfen, ihren Code zu debuggen.

Ich gehe meinen Weg
quelle
4

In meinem Fall trat dieser Fehler nicht aufgrund doppelter Werte auf, sondern weil ich versucht habe, eine kürzere Serie mit einem Datenrahmen zu verbinden: Beide hatten denselben Index, aber die Serie hatte weniger Zeilen (wobei die obersten fehlten). Folgendes hat für meine Zwecke funktioniert:

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
quelle
Danke dir! Ich hatte mich daran gewöhnt, DataFrames und Serien wie folgt zu filtern und später zusammenzuführen: df_larger_dataframe['values'] = df_filtered_dataframe['filtered_values'] und es hat in letzter Zeit bei TimeSeries nicht funktioniert - Ihr Code hat es gelöst!
tw0000
2

Ich habe ein paar Stunden mit dem gleichen Thema verschwendet. In meinem Fall musste ich_index () eines Datenrahmens zurücksetzen, bevor ich die Apply- Funktion verwenden konnte. Vor dem Zusammenführen oder Nachschlagen von einem anderen indizierten Dataset müssen Sie den Index zurücksetzen, da 1 Dataset nur 1 Index haben kann.

Rishi Jain
quelle
2

Einfache Lösung, die bei mir funktioniert hat

Führen Sie df.reset_index(inplace=True)vor Gruppierung.

Vielen Dank an diesen Github-Kommentar für die Lösung.

Connor
quelle
@Chris_vr Entfernen Sie den Inplace-Teil, wenn Sie möchten, dass er den Datenrahmen zurückgibt
Connor