Reindexing only valid with uniquely valued Index objectsの確認ポイント

概要

pandasでconcatをしたところ下記のエラーが発生した。

InvalidIndexError: Reindexing only valid with uniquely valued Index objectsReindexing only valid with uniquely valued Index objects

エラーメッセージには、「IndexがユニークでなくReindexできない」といったメッセージが表示されている。
このエラーが出た際には2点の確認が必要であったので記録しておく。

重要な確認ポイントは次の2つ。

  1. Indexが重複していないか
  2. Columnが重複していないか

Indexの重複については、reset_index()concat(ignore_index=True)で解決できる。
Columnの重複については、df = df.loc[:,~df.columns.duplicated()] で重複したカラムを削除できるようだ。

事象

特徴量エンジニアリングでDataFrameを縦に横にconcatしていると、indexやcolumnが肥大化してしまい、今回のような事象に遭遇するかもしれない。

簡単なコードで事象を説明する。
下記の2つのDataFrameを定義する。

df1 = pd.DataFrame({'A': ['A0', 'A1', 'A2', 'A3'],
                    'B': ['B0', 'B1', 'B2', 'B3'],
                    'C': ['C0', 'C1', 'C2', 'C3'],
                    'D': ['D0', 'D1', 'D2', 'D3']},
                    index=[0, 1, 2, 3])
	A	B	C	D
0	A0	B0	C0	D0
1	A1	B1	C1	D1
2	A2	B2	C2	D2
3	A3	B3	C3	D3

df2 = pd.DataFrame({'A': ['A4', 'A5', 'A6', 'A7'],
                    'B': ['B4', 'B5', 'B6', 'B7'],
                    'C': ['C4', 'C5', 'C6', 'C7'],
                    'D': ['D4', 'D5', 'D6', 'D7']},
                    index=[0, 1, 2, 3])
	A	B	C	D
0	A4	B4	C4	D4
1	A5	B5	C5	D5
2	A6	B6	C6	D6
3	A7	B7	C7	D7

これらdf1, df2を縦、横にconcatするのは問題なくできる。

df3 = pd.concat([df1, df2], axis=0)
	A	B	C	D
0	A0	B0	C0	D0
1	A1	B1	C1	D1
2	A2	B2	C2	D2
3	A3	B3	C3	D3
0	A4	B4	C4	D4
1	A5	B5	C5	D5
2	A6	B6	C6	D6
3	A7	B7	C7	D7

df4 = pd.concat([df1, df2], axis=1)
	A	B	C	D	A	B	C	D
0	A0	B0	C0	D0	A4	B4	C4	D4
1	A1	B1	C1	D1	A5	B5	C5	D5
2	A2	B2	C2	D2	A6	B6	C6	D6
3	A3	B3	C3	D3	A7	B7	C7	D7

ここでdf3, df1を横にconcatするとエラーが発生する。(Indexの重複)
縦にconcatは可能。

pd.concat([df3, df1], axis=1)
InvalidIndexError: Reindexing only valid with uniquely valued Index objects

pd.concat([df3, df1], axis=0)
	A	B	C	D
0	A0	B0	C0	D0
1	A1	B1	C1	D1
2	A2	B2	C2	D2
3	A3	B3	C3	D3
0	A4	B4	C4	D4
1	A5	B5	C5	D5
2	A6	B6	C6	D6
3	A7	B7	C7	D7
0	A0	B0	C0	D0
1	A1	B1	C1	D1
2	A2	B2	C2	D2
3	A3	B3	C3	D3

さらにdf4とdf1を縦にconcatするとエラーが発生する。(Columnの重複)
横にconcatは可能。

pd.concat([df4, df1], axis=0)
InvalidIndexError: Reindexing only valid with uniquely valued Index objects

pd.concat([df4, df1], axis=1)
	A	B	C	D	A	B	C	D	A	B	C	D
0	A0	B0	C0	D0	A4	B4	C4	D4	A0	B0	C0	D0
1	A1	B1	C1	D1	A5	B5	C5	D5	A1	B1	C1	D1
2	A2	B2	C2	D2	A6	B6	C6	D6	A2	B2	C2	D2
3	A3	B3	C3	D3	A7	B7	C7	D7	A3	B3	C3	D3

解決策

Indexの重複に関してはreset_index()で対処する。

tmp = df3.reset_index(drop=True)
display(tmp)
	A	B	C	D
0	A0	B0	C0	D0
1	A1	B1	C1	D1
2	A2	B2	C2	D2
3	A3	B3	C3	D3
4	A4	B4	C4	D4
5	A5	B5	C5	D5
6	A6	B6	C6	D6
7	A7	B7	C7	D7

pd.concat([tmp, df1], axis=1)
	A	B	C	D	A	B	C	D
0	A0	B0	C0	D0	A0	B0	C0	D0
1	A1	B1	C1	D1	A1	B1	C1	D1
2	A2	B2	C2	D2	A2	B2	C2	D2
3	A3	B3	C3	D3	A3	B3	C3	D3
4	A4	B4	C4	D4	NaN	NaN	NaN	NaN
5	A5	B5	C5	D5	NaN	NaN	NaN	NaN
6	A6	B6	C6	D6	NaN	NaN	NaN	NaN
7	A7	B7	C7	D7	NaN	NaN	NaN	NaN

Columnの重複に関しては df = df.loc[:,~df.columns.duplicated()] で対処する。

tmp = df4.loc[:,~df4.columns.duplicated()] 
display(tmp)
	A	B	C	D
0	A0	B0	C0	D0
1	A1	B1	C1	D1
2	A2	B2	C2	D2
3	A3	B3	C3	D3

pd.concat([tmp, df1], axis=0)
	A	B	C	D
0	A0	B0	C0	D0
1	A1	B1	C1	D1
2	A2	B2	C2	D2
3	A3	B3	C3	D3
0	A0	B0	C0	D0
1	A1	B1	C1	D1
2	A2	B2	C2	D2
3	A3	B3	C3	D3

まとめ

ここで述べた対処法は、重複Index, Columnを削除する方針である。
もし重複Index, Columnを残してconcatしたいのであれば、rename()重複Index, Columnを名前変更してconcatすると良いと思う。

Pythonpandas,python

Posted by masa