おそらく、MultiIndex を使用することで、両方の長所を活かすことができます。
import numpy as np
import pandas as pd
df = pd.DataFrame(np.arange(8).reshape(4,2), index=['a_1', 'b_2', 'c_3', 'c_4'])
print(df)
# 0 1
# a_1 0 1
# b_2 2 3
# c_3 4 5
# c_4 6 7
index = pd.MultiIndex.from_tuples([item.split('_') for item in df.index])
df.index = index
print(df)
# 0 1
# a 1 0 1
# b 2 2 3
# c 3 4 5
# 4 6 7
このようにして、インデックスの最初のレベルに従って物事にアクセスできます。
In [30]: df.ix['c']
Out[30]:
0 1
3 4 5
4 6 7
またはインデックスの両方のレベルに従って:
In [31]: df.ix[('c','3')]
Out[31]:
0 4
1 5
Name: (c, 3)
さらに、すべての DataFrame メソッドは、MultiIndices を使用して DataFrame で動作するように構築されているため、何も失うことはありません。
ただし、本当にインデックスの第 2 レベルを削除したい場合は、次のようにすることができます。
df.reset_index(level=1, drop=True, inplace=True)
print(df)
# 0 1
# a 0 1
# b 2 3
# c 4 5
# c 6 7