将 pandas 数据框中的二级索引重置为从 1 开始
Reset secondary index in pandas dataframe to start at 1
假设我构建了一个多索引数据框,如下所示:
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'])
sec_ind 从 1 向上顺序运行,但我想重置第二个索引,以便对于每个 prim_ind 级别,sec_ind 始终从 1 开始。我有一直在尝试解决我是否可以使用重置索引来执行此操作,但失败得很惨。
我知道我可以遍历数据框来获得这个结果,但这将是一种可怕的方法,必须有一种更像 pythonic 的方法——有人能帮忙吗?
注意:我正在使用的数据框实际上是从 csv 导入的,上面的代码只是为了说明这个问题。
您可以使用 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
假设我构建了一个多索引数据框,如下所示:
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'])
sec_ind 从 1 向上顺序运行,但我想重置第二个索引,以便对于每个 prim_ind 级别,sec_ind 始终从 1 开始。我有一直在尝试解决我是否可以使用重置索引来执行此操作,但失败得很惨。
我知道我可以遍历数据框来获得这个结果,但这将是一种可怕的方法,必须有一种更像 pythonic 的方法——有人能帮忙吗?
注意:我正在使用的数据框实际上是从 csv 导入的,上面的代码只是为了说明这个问题。
您可以使用 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