0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

[Python / pandas] concat 使用時の InvalidIndexError: Reindexing only valid with uniquely valued Index objects エラー発生原因パターン

Posted at

1. 概要

pandas の concat 関数を使用していて、 InvalidIndexError: Reindexing only valid with uniquely valued Index objects に出会したのだが、心当たりがなく、原因究明に時間を要したので記事にしておく。

2. 前提

item version など
python 3.10
pandas 2.2.0

3. 発生原因

3-1. エラーにならないパターン

これは OK。

import pandas as pd

# サンプルのDataFrame
data = pd.DataFrame({
    'A': [1, 2, 3],
    'B': [4, 5, 6],
    'C': [7, 8, 9]
},index=pd.RangeIndex(0, 3))

pd.concat([data, data], axis=0)

# 結果
	A	B	C
0	1	4	7
1	2	5	8
2	3	6	9
0	1	4	7
1	2	5	8
2	3	6	9

エラーメッセージには Index という文言が入っているが、 Index が重複していてもエラーにはならない

そして、なんと驚くことに、単に列名が重複していている場合にもエラーにならない。

pd.concat([data, data], axis=1)

# 結果
	A	B	C	A	B	C
0	1	4	7	1	4	7
1	2	5	8	2	5	8
2	3	6	9	3	6	9

じゃあ何がエラー原因なんだい?

3-2. わかりやすいエラー原因

3-2-1. concat 前から Index 重複

元々 Index が1つ以上重複する DataFrame を axis=1 方向に concat しようとすると発生する。以下のような状況。

df1 = pd.DataFrame(
    {"体重": [50.1, 69.3], "身長": [163.4, 178.1]},
    index =["たじまさん", "Kevin"]
)
df2 = pd.DataFrame(
    {"学歴": ["大卒", "大卒"], "総資産": [1e10, 1.2e12]},
    index =["たじまさん", "たじまさん"]  # concat 前から index 重複
)

pd.concat([df1, df2], axis=1)

# 結果
InvalidIndexError: Reindexing only valid with uniquely valued Index objects

どうやら、 concat で結合する前から index が重複しているとエラーになるらしい。

3-2-2. concat 前から columns 重複

元々 Columns が名1つ以上重複する DataFrame を axis=0 方向に concat しようとしてもエラーが発生する。以下のような状況。

サンプルデータを作るのが少し難しいが、以下のようなパターンがありうる。

df1 = pd.DataFrame(
    {"体重": [50.1, 69.3], "身長": [163.4, 178.1]},
    index =["たじまさん", "Kevin"]
)
df1

# 結果
    	体重 	身長
たじまさん 50.1	163.4
Kevin    69.3	178.1

上の DataFrame はよくある形式。

一方、下のような DataFrame は、手を入れないと作れない。

seriesA = pd.Series([42.6, 48.5], name="体重")
seriesB = seriesA.copy()
df2 = pd.concat([seriesA, seriesB], axis=1)
df2.index = ["よこたさん", "Comet"]
df2

# 結果
             体重	体重
よこたさん	42.6	42.6
Comet   	48.5	48.5

こういうのを縦 (axis=0) に concat するとエラーが出る。

pd.concat([df1, df2], axis=0)

# 結果
InvalidIndexError: Reindexing only valid with uniquely valued Index objects

ここまでは色々な記事に書かれているので、これが原因だったらすぐに気がつけると思う。

3-3. 見落としがちなパターン

ここからは、なかなか気がつきにくいパターン。

再度、同じ列名を含む DataFrame に登場してもらう。

seriesA = pd.Series([1, 2, 3], name='A')
seriesB = pd.Series([4, 5, 6], name='A')
df_A = pd.concat([seriesA, seriesA, seriesB], axis=1)
df_A

# 結果
	A	A	A
0	1	1	4
1	2	2	5
2	3	3	6

実は、こういう DataFrame も、縦 (axis=0) 方向に結合できる。

pd.concat([df_A, df_A], axis=0)

# 結果
	A	A	A
0	1	1	4
1	2	2	5
2	3	3	6
0	1	1	4
1	2	2	5
2	3	3	6

自分の場合はこうした上記のような処理を書いていた。

ところが、入力データの形式によって、たまたま、1列だけ列名が変わることがあった。
出来上がったデータはこんな感じ。

seriesA = pd.Series([1, 2, 3], name='A')
seriesC = pd.Series([7, 8, 9], name='C')
df_C = pd.concat([seriesA, seriesA, seriesC], axis=1)
df_C

# 結果
	A	A	C
0	1	1	7
1	2	2	8
2	3	3	9

これを df_A と縦に concat したら、以下のようになりそうなのだけど、、、

	A	A	A	C
0	1	1	4	Nan
1	2	2	5	Nan
2	3	3	6	Nan
0	1	1	Nan	7
1	2	2	Nan	8
2	3	3	Nan	9

実際は InvalidIndexError になる。

pd.concat([df_A, df_C], axis=0)

# 結果
InvalidIndexError: Reindexing only valid with uniquely valued Index objects

4. 考察

要は、 「Reindexing (自動での Index や Columns 書き換え)」 が肝なのだろう。

  • 「Reindexing」がなければ、 Index、 Columns が重複してようが問題ない
  • 「Reindexing」が pandas 内で自動で実行されるときは、重複した Index や Columns を持ってきてはならない

ということだと思われる。

つまり、 Columns や Index の書き換えが発生せずに、元のままで結合後の DataFrame が作られる時は、エラーは発生しない。

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?