将列标签的级别附加到MultiIndex

时间:2016-06-07 16:01:26

标签: python pandas

我正在尝试在MultiIndex中更改单个级别的列标签。

例如,

test = pd.DataFrame(np.random.random((4,4)))
test.columns = pd.MultiIndex.from_product([['Level1'],['A','B','C','D'],['Level3']])

Out: 
     Level1                              
          A         B         C         D
     Level3    Level3    Level3    Level3
0  0.153388  0.253070  0.338756  0.025598
1  0.818954  0.169352  0.851079  0.823263
2  0.535703  0.432627  0.690446  0.599997
3  0.304654  0.919936  0.095747  0.404449

我想改变第3级&#39;标签为[&#39; 1&#39;,&#39; 2&#39;,&#39; 3&#39;,&#39; 4&#39;]但无法找到干净的方法。< / p>

我尝试了下面的内容,它提供了16个元素的迭代,所以不是我需要的。

test.columns = pd.MultiIndex.from_product([['Level1'],['A','B','C','D'],['1','2','3','4']])

我发现的唯一解决方法是在开始时手动定义每个级别并重新定义MultiIndex

例如

level1 = ['Level1','Level1','Level1','Level1']
level2 = ['A','B','C','D']
level3 = ['1','2','3','4']
test = pd.DataFrame(np.random.random((4,4)),columns=[level1,level2,level3])

有更整洁的解决方案吗?我正在处理大型数据集,因此上述内容非常繁琐。

2 个答案:

答案 0 :(得分:1)

IIUC您需要设置级别值,然后分两步设置标签:

In [153]:
test.columns = test.columns.set_levels(['0','1','2','3'],level=2)
test.columns = test.columns.set_labels([0,1,2,3],level=2)
test

Out[153]:
     Level1                              
          A         B         C         D
          0         1         2         3
0  0.122865  0.778640  0.582170  0.695648
1  0.051477  0.479084  0.150539  0.143929
2  0.362087  0.285109  0.465092  0.205157
3  0.963744  0.730001  0.148460  0.474678

原因是因为最初你的第三级都有重复列的相同标签(0):

In [155]:
test.columns

Out[155]:
MultiIndex(levels=[['Level1'], ['A', 'B', 'C', 'D'], ['Level3']],
           labels=[[0, 0, 0, 0], [0, 1, 2, 3], [0, 0, 0, 0]])

但你想要的是重命名水平和标签,导致以下结果:

In [158]:
test.columns

Out[158]:
MultiIndex(levels=[['Level1'], ['A', 'B', 'C', 'D'], ['0', '1', '2', '3']],
           labels=[[0, 0, 0, 0], [0, 1, 2, 3], [0, 1, 2, 3]])

因此,您可以在已经尝试过的情况下再次重建多指数,或者设置水平值,然后将标签值设置为上面显示的

答案 1 :(得分:0)

或者,您可以使用pd.MultiIndex.from_tuples

test = pd.DataFrame(np.random.random((4,4)))
index_tuples = [('Level1',letter,number) for letter,number in zip(['A','B','C','D'],range(1,4+1))]
test.columns = pd.MultiIndex.from_tuples(index_tuples)