Pandas:更改具有多级列的数据框中的特定列名称

sh.*_*eon 7 python dataframe multi-level pandas

我想找到更改多级数据框中特定列的更改名称的方法.

有了这些数据:

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)
Run Code Online (Sandbox Code Playgroud)

此代码无效:

dataDF.rename(columns = {('A', '1', 'I'):('Z', '100', 'Z')}, inplace=True)
Run Code Online (Sandbox Code Playgroud)

结果:

    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
Run Code Online (Sandbox Code Playgroud)

而且也不是:

dataDF.columns.values[0] = ('Z', '100', 'Z')
Run Code Online (Sandbox Code Playgroud)

结果:

    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
Run Code Online (Sandbox Code Playgroud)

但结合以上代码工作!!!

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

结果:

    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
Run Code Online (Sandbox Code Playgroud)

这是熊猫的错误​​吗?

piR*_*red 11

这是我的理论

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

dataDF.columns[0] = ('Z', '100', 'Z')
Run Code Online (Sandbox Code Playgroud)
---------------------------------------------------------------------------
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
Run Code Online (Sandbox Code Playgroud)

但是熊猫无法控制你做什么values属性.

dataDF.columns.values[0] = ('Z', '100', 'Z')
Run Code Online (Sandbox Code Playgroud)

我们看到dataDF.columns看起来一样,但dataDF.columns.values清楚地反映了这种变化.不幸的是,df.columns.values并不是数据框显示的内容.


另一方面,这看起来确实应该有效.事实上,我觉得不对.

dataDF.rename(columns={('A', '1', 'I'): ('Z', '100', 'Z')}, inplace=True)
Run Code Online (Sandbox Code Playgroud)

我相信这只在更改了值之后才起作用的原因是,rename它通过查看值来强制重建列.由于我们更改了值,现在可以使用了.这是非常kludgy,我不建议建立一个依赖于此的过程.


我的推荐

  • 标识要更改的列名称的位置
  • 将列的名称指定给值数组
  • 从头开始构建新列,明确

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]
Run Code Online (Sandbox Code Playgroud)

  • `dataDF.columns.values[0] = ('Z', '100', 'Z')` 对我有用。之后打印“dataDF.columns”正确反映了更改。我在这里缺少什么?pandas 在新版本中修复了这个问题吗? (4认同)