【问题标题】:Pandas: Change a specific column name in dataframe having multilevel columns熊猫:更改具有多级列的数据框中的特定列名
【发布时间】:2016-11-07 06:44:13
【问题描述】:

我想找到在多级数据框中更改特定列名称的方式。

有了这些数据:

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

这是熊猫的bug吗?

【问题讨论】:

    标签: python pandas dataframe multi-level


    【解决方案1】:

    这是我的理论

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

    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
    

    【讨论】:

    • dataDF.columns.values[0] = ('Z', '100', 'Z') 为我工作。之后打印dataDF.columns 正确反映了更改。我在这里想念什么? pandas 在更新的版本中解决了这个问题吗?
    【解决方案2】:

    你可以像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']]一样简单地改变它

    【讨论】:

    • 我仍然不确定它的错误是否如你所说。
    【解决方案3】:

    我遇到了这个问题,因为我自己试图找到在具有多个级别的数据框中重命名列名的解决方案。我尝试了@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
    

    【讨论】:

      猜你喜欢
      • 2020-08-06
      • 1970-01-01
      • 1970-01-01
      • 2018-04-25
      • 2022-11-15
      • 1970-01-01
      • 1970-01-01
      • 2017-08-21
      • 2015-03-29
      相关资源
      最近更新 更多