2016-11-07 65 views
3

我想要查找多级数据框中特定列的更改名称的方式。熊猫:更改具有多级列的数据框中的特定列名称

有了这些数据:

data = { 
    ('A', '1', 'I'): [1, 2, 3, 4, 5], 
    ('B', '2', 'II'): [1, 2, 3, 4, 5], 
    ('C', '3', 'I'): [1, 2, 3, 4, 5], 
    ('D', '4', 'II'): [1, 2, 3, 4, 5], 
    ('E', '5', 'III'): [1, 2, 3, 4, 5], 
} 

dataDF = pd.DataFrame(data) 

这个代码不工作:

dataDF.rename(columns = {('A', '1', 'I'):('Z', '100', 'Z')}, inplace=True) 

结果:

A B C D E 
    1 2 3 4 5 
    I II I II III 
0 1 1 1 1 1 
1 2 2 2 2 2 
2 3 3 3 3 3 
3 4 4 4 4 4 
4 5 5 5 5 5 

而且也没有:

dataDF.columns.values[0] = ('Z', '100', 'Z') 

结果:

A B C D E 
    1 2 3 4 5 
    I II I II III 
0 1 1 1 1 1 
1 2 2 2 2 2 
2 3 3 3 3 3 
3 4 4 4 4 4 
4 5 5 5 5 5 

但随着工作上面的代码组合!

dataDF.columns.values[0] = ('Z', '100', 'Z') 
dataDF.rename(columns = {('A', '1', 'I'):('Z', '100', 'Z')}, inplace=True) 
dataDF 

结果:

Z B C D E 
    100 2 3 4 5 
    Z II I II III 
0 1 1 1 1 1 
1 2 2 2 2 2 
2 3 3 3 3 3 
3 4 4 4 4 4 
4 5 5 5 5 5 

是大熊猫的这种错误?

回答

4

这是我的理论

大熊猫不希望pd.Index s到是可变的。我们可以看到这一点,如果我们试图更改索引的第一个元素自己

dataDF.columns[0] = ('Z', '100', 'Z') 
--------------------------------------------------------------------------- 
TypeError         Traceback (most recent call last) 
<ipython-input-32-2c0b76762235> in <module>() 
----> 1 dataDF.columns[0] = ('Z', '100', 'Z') 

//anaconda/envs/3.5/lib/python3.5/site-packages/pandas/indexes/base.py in __setitem__(self, key, value) 
    1372 
    1373  def __setitem__(self, key, value): 
-> 1374   raise TypeError("Index does not support mutable operations") 
    1375 
    1376  def __getitem__(self, key): 

TypeError: Index does not support mutable operations 

但大熊猫无法控制你做什么的values属性。

dataDF.columns.values[0] = ('Z', '100', 'Z') 

我们看到dataDF.columns看起来一样,但dataDF.columns.values清楚地反映了变化。不幸的是,df.columns.values不是显示在数据框中的东西。


另一方面,这确实看起来应该起作用。事实上,它不会感觉我错了。

dataDF.rename(columns={('A', '1', 'I'): ('Z', '100', 'Z')}, inplace=True) 

我相信这只是已经改变的值之后的作品,原因是rename通过观察值迫使列的重建。由于我们改变了价值观,现在它起作用了。这是非常糟糕的,我不建议建立一个依赖于此的流程。


我的建议

  • 识别列名的位置,你想改变
  • 列的指定名称值的阵列
  • 从头开始建立新的栏目,明确地

from_col = ('A', '1', 'I') 
to_col = ('Z', '100', 'Z') 
colloc = dataDF.columns.get_loc(from_col) 
cvals = dataDF.columns.values 
cvals[colloc] = to_col 

dataDF.columns = pd.MultiIndex.from_tuples(cvals.tolist()) 

dataDF 

[![enter code here][1]][1] 
+0

感谢您的解释! –

+0

不用客气 – piRSquared

0

您可以简单地改变它像DF.columns.levels=[[u'Z', u'B', u'C', u'D', u'E'],[u'5', u'2', u'3', u'4', u'5'],[u'IIIIII', u'II', u'III']]

+0

我还不确定它的bug是否如你所说。 –

+0

感谢您的解释! –

相关问题