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つ。
- Indexが重複していないか
- 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すると良いと思う。
ディスカッション
コメント一覧
まだ、コメントがありません