将pandas dataframe中的二级索引重置为1

时间:2017-09-11 13:09:19

标签: python pandas dataframe multi-index

假设我构建了一个多索引数据框,如下所示:

prim_ind=np.array(range(0,1000))
for i in range(0,1000):
    prim_ind[i]=round(i/4)

d = {'prim_ind' :prim_ind,
     'sec_ind' : np.array(range(1,1001)),
     'a' : np.array(range(325,1325)),
     'b' : np.array(range(8318,9318))}

df= pd.DataFrame(d).set_index(['prim_ind','sec_ind'])

enter image description here

sec_ind从1向上顺序运行,但是我想重置第二个索引,以便对于每个prim_ind级别,sec_ind始终从1开始。我一直试图解决,如果我可以使用重置索引来执行此操作但我惨遭失败。

我知道我可以迭代数据框来获得这个结果,但这将是一种可怕的方式来实现它并且必须有更多的pythonic方式 - 任何人都可以帮助吗?

注意:我正在使用的数据帧实际上是从csv导入的,上面的代码只是为了说明这个问题。

1 个答案:

答案 0 :(得分:1)

您可以将cumcount用于计数类别。

df.index = [df.index.get_level_values(0), df.groupby(level=0).cumcount() + 1]

或者更好的是,如果还需要索引名称,请使用MultiIndex.from_arrays

df.index = pd.MultiIndex.from_arrays([df.index.get_level_values(0), 
                                      df.groupby(level=0).cumcount() + 1], 
                                      names=df.index.names)
print (df)
                     a     b
prim_ind sec_ind            
0        1         325  8318
         2         326  8319
         3         327  8320
1        1         328  8321
         2         329  8322
         3         330  8323
2        1         331  8324

因此,列sec_ind不是必需的,您也可以使用:

d = {'prim_ind' :prim_ind,
     'a' : np.array(range(325,1325)),
     'b' : np.array(range(8318,9318))}

df = pd.DataFrame(d)
print (df.head(8))
     a     b  prim_ind
0  325  8318         0
1  326  8319         0
2  327  8320         0
3  328  8321         1
4  329  8322         1
5  330  8323         1
6  331  8324         2
7  332  8325         2

df = df.set_index(['prim_ind', df.groupby('prim_ind').cumcount() + 1]) \
       .rename_axis(('first','second'))
print (df.head(8))

                a     b
first second           
0     1       325  8318
      2       326  8319
      3       327  8320
1     1       328  8321
      2       329  8322
      3       330  8323
2     1       331  8324
      2       332  8325