熊猫重置MultiIndex的内部级别

时间:2018-08-13 18:31:08

标签: python pandas

我有以下格式的DF:

                   col1    col2
ID          Date
 1    1993-12-31      4       6
      1994-12-31      8       5
      1995-12-31      4       7
      1996-12-31      3       3
 2    2000-12-31      7       8
      2001-12-31      5       9
      2002-12-31      8       4

我想重置“日期”索引,并给出以下信息:

             col1    col2
ID    Date
 1       0      4       6
         1      8       5
         2      4       7
         3      3       3
 2       0      7       8
         1      5       9
         2      8       4

我以为df.reset_index(level='Date', inplace=True, drop=True)可以做到,但事实并非如此。

4 个答案:

答案 0 :(得分:5)

使用set_indexcumcount

tmp = df.reset_index('Date', drop=True)
tmp.set_index(df.groupby(level=0).cumcount().rename('Date'), append=True)

         col1  col2
ID Date
1  0        4     6
   1        8     5
   2        4     7
   3        3     3
2  0        7     8
   1        5     9
   2        8     4

答案 1 :(得分:4)

您可以对ID进行分组,然后使用apply重设每个组的索引:

new_df = (df.groupby(df.index.get_level_values('ID'))
          .apply(lambda x: x.reset_index()).drop(['ID','Date'],1))

new_df.index = new_df.index.rename(['ID','Date'])

>>> new_df
         col1  col2
ID Date            
1  0        4     6
   1        8     5
   2        4     7
   3        3     3
2  0        7     8
   1        5     9
   2        8     4

答案 2 :(得分:4)

使用pd.MultiIndex.from_arraysgroupby + cumcount

df.index = pd.MultiIndex.from_arrays(
    [df.index.get_level_values(0), df.groupby(level=0).cumcount()],
    names=['ID', 'Date'])

df
         col1  col2
ID Date            
1  0        4     6
   1        8     5
   2        4     7
   3        3     3
2  0        7     8
   1        5     9
   2        8     4

这不会推广到N级,但我应该忘记的是一个df.index.set_levels等价物...

答案 3 :(得分:3)

新答案

不像以前的答案那么酷,但我宁愿准确而不是酷。

from collections import defaultdict
from itertools import count
d = defaultdict(count)

lbl = []
for a, *_ in df.index.values:
    lbl.append(next(d[a]))

lvl = pd.RangeIndex(max(lbl) + 1)

df.set_index(df.index.set_labels(lbl, 1).set_levels(lvl, 1))

         col1  col2
ID Date            
1  0        4     6
   1        8     5
   2        4     7
   3        3     3
2  0        7     8
   1        5     9
   2        8     4

旧答案

请勿使用

我误解了问题。我没有看到需要为每个组重置新索引。

希望对某人有用。

您可以使用pandas.MultiIndex.set_levels

n = 1
lvl = df.index.levels[n]
new_lvl = pd.RangeIndex(len(lvl))
new_idx = df.index.set_levels(new_lvl, n)
df.set_index(new_idx)

         col1  col2
ID Date            
1  0        4     6
   1        8     5
   2        4     7
   3        3     3
2  4        7     8
   5        5     9
   6        8     4

单行

是的! \o/

df.set_index(df.index.set_levels(pd.RangeIndex(len(df.index.levels[1])), 1))

         col1  col2
ID Date            
1  0        4     6
   1        8     5
   2        4     7
   3        3     3
2  4        7     8
   5        5     9
   6        8     4

就地

df.index.set_levels(pd.RangeIndex(len(df.index.levels[1])), 1, inplace=True)
df

         col1  col2
ID Date            
1  0        4     6
   1        8     5
   2        4     7
   3        3     3
2  4        7     8
   5        5     9
   6        8     4