Date

pandasの列は、indexとcolumnからなる。これを入れ替えるには、rename_axis().reset_index().set_index()をつかう。

In [1]:
df = pd.DataFrame(index=list('abcde')).assign(iroha=list('イロハニホ'),even=np.arange(5)%2==1)
df
Out[1]:
iroha even
a False
b True
c False
d True
e False

reset_index()の挙動

reset_index() は、今のindexをcolumnに移して、新しい連番のindexをふる。

元々、df.index.nameは空になっている。columnに移るためには名前がつかなくてはいけないので、defaultで'index'という名前がつく。

In [2]:
df.reset_index()
Out[2]:
index iroha even
0 a False
1 b True
2 c False
3 d True
4 e False

すでにdfに'indexという名のcolumnがある場合は、'level_0'という名が振られる.

In [3]:
df.assign(index=df.iroha).reset_index()
Out[3]:
level_0 iroha even index
0 a False
1 b True
2 c False
3 d True
4 e False

'index'も'level_0'もcolumnにある場合は、失敗する.

In [4]:
df.assign(index=df.iroha, level_0='df.iroha').reset_index()
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-4-3820023a1c0e> in <module>()
----> 1 df.assign(index=df.iroha, level_0='df.iroha').reset_index()

/opt/conda/lib/python3.6/site-packages/pandas/core/frame.py in reset_index(self, level, drop, inplace, col_level, col_fill)
   4137                 # to ndarray and maybe infer different dtype
   4138                 level_values = _maybe_casted_values(lev, lab)
-> 4139                 new_obj.insert(0, name, level_values)
   4140 
   4141         new_obj.index = new_index

/opt/conda/lib/python3.6/site-packages/pandas/core/frame.py in insert(self, loc, column, value, allow_duplicates)
   3220         value = self._sanitize_column(column, value, broadcast=False)
   3221         self._data.insert(loc, column, value,
-> 3222                           allow_duplicates=allow_duplicates)
   3223 
   3224     def assign(self, **kwargs):

/opt/conda/lib/python3.6/site-packages/pandas/core/internals.py in insert(self, loc, item, value, allow_duplicates)
   4336         if not allow_duplicates and item in self.items:
   4337             # Should this be a different kind of error??
-> 4338             raise ValueError('cannot insert {}, already exists'.format(item))
   4339 
   4340         if not isinstance(loc, int):

ValueError: cannot insert level_0, already exists

そのため、reset_indexを連続で使っても失敗する

In [5]:
# df.reset_index()
# df.reset_index().reset_index()
# df.reset_index().reset_index().reset_index() -> fail ValueError: cannot insert level_0, already exists

set_indexの挙動

set_indexは現在のindexを捨てて、columnから新たなindexを設定する。

In [6]:
df.set_index('iroha')
Out[6]:
even
iroha
False
True
False
True
False

元々のindexを温存して、indexとcolumnを入れ替えるには、reset_index().set_indexをつかう

In [7]:
df.reset_index().set_index('iroha')
Out[7]:
index even
iroha
a False
b True
c False
d True
e False

indexの名前を変更したい場合は、indexの名前を設定してからおこなう。 df.index.name = 'new_index_name' でもよいが、chain形式でかくにはrename_axisを使う

In [8]:
df.rename_axis('new_index_name').reset_index().set_index('iroha')
Out[8]:
new_index_name even
iroha
a False
b True
c False
d True
e False

Comments

comments powered by Disqus