我想找到在多级数据帧中更改特定列名称的方法。
使用此数据:
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
这是熊猫的虫子吗?
最佳答案
这是我的理论
熊猫不希望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
但是pandas无法控制您执行的
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]