これまで紹介してきたpandasのデータ構造、シリーズやデータフレームは、軸のラベルやname属性などを保持する機能を持っているが、これをインデックスオブジェクトという。

まずはインデックスオブジェクトについてコードを見ながら確認しよう。

import pandas as pd
from pandas import Series

sr = pd.Series(range(3), index=['a', 'b', 'c'])
print(sr)
# a    0
# b    1
# c    2
# dtype: int64

sr_index = sr.index
print(sr_index)
# Index(['a', 'b', 'c'], dtype='object')

これはシリーズを使った例で、index属性を使ってシリーズのインデックスオブジェクトをsr_indexに格納している。

なお、インデックスオブジェクトは後から変更することができない。

sr_index[1] = 'd' # TypeError発生!

変更不可であることにより、下記の例のようにデータ構造を安全に共有することができるのだ。

import pandas as pd
import numpy as np
from pandas import Series

labels = pd.Index(np.arange(3))
labels
# Int64Index([0, 1, 2], dtype='int64')

data = pd.Series([5, 6, 7], index=labels)
data
# 0    5
# 1    6
# 2    7
# dtype: int64

また、インデックスオブジェクトは固定長のセットとしても扱うことができる。

セットについては下記の記事で詳しくまとめているので、参考にしてくれ。

import pandas as pd
from pandas import DataFrame

data = {'shop_a': [5000, 12000],
       'shop_b': [3000, 5000],
       'shop_c': [8000, 9000]}
df = pd.DataFrame(data, index=[2017, 2018])
df
'shop_a' in df.columns # True
'shop_d' in df.columns # False
2019 in df.index # False
2018 in df.index # True

Python標準のセットと大きく異なる点は、重複したラベルを持つことができるということだ。

import pandas as pd
from pandas import DataFrame

dup = pd.Index(['taro', 'taro', 'jiro', 'jiro'])
dup
# Index(['taro', 'taro', 'jiro', 'jiro'], dtype='object')

重複したラベルでデータを検索すると、指定のラベルに該当するデータ全てが抽出される。

なお、本記事では詳しく取り上げないが、Python標準のセット同様、インデックスオブジェクトはuniqueメソッドなど、多くのメソッドや属性を持っているので、インデックスオブジェクトに対して集合演算をおこなうこともできるので、興味があれば詳しく調べてみると良いだろう。