Що означає "ValueError: не вдається перевстановити з дублікату осі"?


254

Я отримую, ValueError: cannot reindex from a duplicate axisколи я намагаюся встановити індекс на певне значення. Я намагався відтворити це простим прикладом, але не зміг цього зробити.

Ось мій сеанс всередині ipdbсліду. У мене є DataFrame з рядковим індексом і цілими стовпцями, знаками з плаваючою вагою. Однак, коли я намагаюся створити sumіндекс для суми всіх стовпців, я отримую ValueError: cannot reindex from a duplicate axisпомилку. Я створив невеликий DataFrame з тими ж характеристиками, але не зміг відтворити проблему, що я можу пропустити?

Я не розумію, що ValueError: cannot reindex from a duplicate axisозначає, що означає це повідомлення про помилку? Можливо, це допоможе мені діагностувати проблему, і це найбільш відповідальна частина мого питання.

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

Ось помилка:

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

Я спробував відтворити це простим прикладом, але мені не вдалося

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
Чи є ймовірність, що ви заблудили справжні назви стовпців своєї матриці спорідненості? (тобто замінив реальні значення чимось іншим, щоб приховати конфіденційну інформацію)
Корем

@Korem, я не думаю, що це правда, але навіть якщо це правда, чому це спричинить вищевказану помилку?
Акавал

2
Я зазвичай бачу це, коли індекс, якому присвоєно значення, має повторювані значення. Оскільки у вашому випадку ви призначаєте рядок, я очікував дубліката у назвах стовпців. Ось чому я запитав.
Корем

@Korem, Дійсно, мої фактичні дані мали дублюючі значення індексу, і я міг відтворити помилку на невеликому прикладі, коли були присутні дублюючі значення індексу. Ви повністю відповіли на моє запитання. Спасибі. Ви не проти поставити це як відповідь?
Акавал

Відповіді:


170

Ця помилка, як правило, зростає при приєднанні / призначенні стовпця, коли індекс має повторювані значення. Оскільки ви присвоюєте рядок, я підозрюю, що в ньому є дублікальне значення affinity_matrix.columns, можливо, не вказане у вашому запитанні.


20
Якщо бути точнішим, у моєму випадку значення було повторене affinity_matrix.index, але я думаю, що це те саме поняття.
Акавал

24
Для тих, хто прийшов до цього пізніше, indexозначає і те, rowі column namesвитратив 20 хвилин на індекс рядків, але виявилося, що я отримав дублюються імена стовпців, які спричинили цю помилку.
Гол Джейсона

Щоб додати це, я зіткнувся з цією помилкою, коли намагався повторно встановити фрейм даних у списку стовпців. Як не дивно, мій дублікат був у моєму оригінальному кадрі даних, тому обов'язково перевірте обидва!
m8_

163

Як говорили інші, ви, мабуть, отримали повторювані значення у своєму початковому індексі. Щоб знайти їх, зробіть це:

df[df.index.duplicated()]


39
Для видалення рядків із дублюючими індексами використовуйте:df = df[~df.index.duplicated()]
tuomastik

4
Для DatetimeIndexред dataframes, ви можете resampleна потрібну частоту , а потім прийняти .first(), .mean()і т.д.
BallpointBen

28

Індекси з повторюваними значеннями часто виникають, якщо ви створюєте DataFrame шляхом об'єднання інших DataFrames. ЯКЩО ви не дбаєте про збереження значень вашого індексу, і хочете, щоб вони були унікальними значеннями, коли ви об'єднуєте дані, встановіть ignore_index=True.

Крім того, замінити ваш поточний індекс новим, замість того df.reindex(), щоб встановити:

df.index = new_index

8
Я використовував ignore_index = True, щоб мій код працював з об'єднаними рамками даних
Габі Лі

Дійсно, ignore_index=Falseце за замовчуванням; якщо використання параметра - це взагалі змінити appendповедінку, це доведеться, тому що ви її встановили True.
Джефрі Бенджамін Браун

17

Для людей, які все ще борються з цією помилкою, це також може статися, якщо ви випадково створили дублікат стовпця з такою ж назвою. Видаліть повторювані стовпці так:

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

12

Просто пропустіть помилку, використовуючи .valuesв кінці.

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

Це саме те , що мені було потрібно! Просто намагаюся створити новий стовпчик, але у мене був індекс із дублікатами в ньому. Використання .valuesзробив трюк
Пол Уайлденхайн

8

Я зіткнувся з цією помилкою сьогодні, коли хотів додати новий стовпчик, як цей

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

Я хотів обробити REMARKстовпець, df_tempщоб повернути 1 або 0. Однак я набрав неправильну змінну df. І вона повернула помилку так:

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

Як ви бачите, правильний код повинен бути

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

Тому що dfі df_tempмають різну кількість рядків. Так воно повернулося ValueError: cannot reindex from a duplicate axis.

Сподіваюся, ви можете це зрозуміти, і моя відповідь може допомогти іншим налагодити їх код.


4

У моєму випадку ця помилка з'явилася не через повторювані значення, а тому, що я намагався приєднати більш коротку серію до Dataframe: обидва мали один і той же індекс, але у серії було менше рядків (не вистачало верхніх кількох). Для моїх цілей працювало наступне:

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

Дякую! Я звик фільтрувати та згодом об’єднувати DataFrames та Series так, df_larger_dataframe['values'] = df_filtered_dataframe['filtered_values'] і останнім часом він не працює на TimeSeries - ваш код вирішив це!
tw0000

2

Я витратив пару годин на те саме питання. У моєму випадку мені довелося скинути_index () фрейму даних, перш ніж використовувати функцію застосувати. Перед об'єднанням або переглядом іншого індексованого набору даних вам потрібно скинути індекс, оскільки 1 набір даних може мати лише 1 індекс.


2

Просте виправлення, яке працювало для мене

Запустити df.reset_index(inplace=True)перед групуванням.

Дякую за цей коментар github за рішення.


@Chris_vr видаліть частину місця, якщо ви хочете, щоб вона повернула рамку даних
Connor
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.