Pandas:更改具有多级列的数据框中的特定列名
Pandas: Change a specific column name in dataframe having multilevel columns
我想找到在多级数据框中更改特定列名称的方法。
有了这个数据:
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
这是 Pandas 的错误吗?
你可以简单地改变它 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']]
这是我的理论
pandas 不希望 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
我遇到这个问题是因为我自己试图找到重命名具有多个级别的数据框中的列名称的解决方案。我尝试了@Dark Matter 提供的解决方案,因为它看起来很简单:
dataDF.columns.levels = [[u'Z', u'B', u'C', u'D', u'E'], [u'100', u'2', u'3', u'4', u'5'], [u'Z', u'II', u'III']]
但是显示错误信息:
C:\anaconda3\lib\site-packages\ipykernel_launcher.py:1: FutureWarning: setting `levels` directly is deprecated. Use set_levels instead
"""Entry point for launching an IPython kernel.
它似乎有效但不再有效。所以我用了:
dataDF.columns.set_levels([['Z', 'B', 'C', 'D', 'E'],
['100', '2', '3', '4', '5'],
['Z', 'II', 'III']],
[0, 1, 2], inplace=True)
结果:dataDF
Z B C D E
100 2 3 4 5
Z II Z 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
我想找到在多级数据框中更改特定列名称的方法。
有了这个数据:
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
这是 Pandas 的错误吗?
你可以简单地改变它 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']]
这是我的理论
pandas 不希望 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
我遇到这个问题是因为我自己试图找到重命名具有多个级别的数据框中的列名称的解决方案。我尝试了@Dark Matter 提供的解决方案,因为它看起来很简单:
dataDF.columns.levels = [[u'Z', u'B', u'C', u'D', u'E'], [u'100', u'2', u'3', u'4', u'5'], [u'Z', u'II', u'III']]
但是显示错误信息:
C:\anaconda3\lib\site-packages\ipykernel_launcher.py:1: FutureWarning: setting `levels` directly is deprecated. Use set_levels instead
"""Entry point for launching an IPython kernel.
它似乎有效但不再有效。所以我用了:
dataDF.columns.set_levels([['Z', 'B', 'C', 'D', 'E'],
['100', '2', '3', '4', '5'],
['Z', 'II', 'III']],
[0, 1, 2], inplace=True)
结果:dataDF
Z B C D E
100 2 3 4 5
Z II Z 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