代码之家  ›  专栏  ›  技术社区  ›  timgeb

用任意顺序和重复的列名重命名多索引列

  •  1
  • timgeb  · 技术社区  · 6 年前

    DataFrame overview (这个问题简称)。

    >>> import pandas as pd
    >>> import numpy as np
    >>>
    >>> index = pd.Index(['Abbott PLC', 'Abbott, Rogahn and Bednar'], dtype='object', name='Account Name')
    >>> columns = pd.MultiIndex(levels=[['total', 'quantity'], ['count', 'sum']], labels=[[0, 0, 1], [1, 0, 1]])
    >>> values = np.array([[755.44,   1.  ,  19.  ], [615.6 ,   1.  ,  18.  ]])
    >>> 
    >>> overview = pd.DataFrame(values, columns=columns, index=index)
    >>> overview
                                total       quantity
                                  sum count      sum
    Account Name                                    
    Abbott PLC                 755.44   1.0     19.0
    Abbott, Rogahn and Bednar  615.60   1.0     18.0
    

    列名很奇怪,因为在我的实际代码中,这个结果是从 数据帧 df

    aggregators = {'total': ['sum', 'count'], 'quantity': 'sum'}
    overview = df.groupby('Account Name')['total', 'quantity'].agg(aggregators)
    

    概述 ,所需结果如下:

                                gross  checkouts  items
    Account Name                                       
    Abbott PLC                 755.44        1.0   19.0
    Abbott, Rogahn and Bednar  615.60        1.0   18.0
    

    我不能简单地使用 overview.columns = ['gross', 'checkouts', 'items'] this similar question 因为使用后 agg 列的顺序是任意的。(正在应用 rename 由于名字重复,看起来也很棘手 'sum'

    目前,我正在使用 OrderedDict 对于 aggregators ,因此 具有确定的列顺序的。但假设 概述 不能逆流而上,我怎么才能优雅地达到我想要的结果呢?

    1 回复  |  直到 6 年前
        1
  •  0
  •   jpp    6 年前

    您的数据帧具有 MultiIndex 作为列。有几种方法可以展平为常规索引:

    pd索引图

    overview.columns = overview.columns.map('_'.join)
    

    使用Python3.6+可以使用格式化的字符串文本( PEP 498

    overview.columns = [f'{i}_{j}' for i, j in overview.columns]
    

    列表理解+str.format/str.join

    对于<3.6版,可以使用 str.format str.join :

    overview.columns = ['{i}_{j}'.format(i, j) for i, j in overview.columns]
    
    overview.columns = list(map('_'.join, overview.columns))
    

    要仅重命名,可以直接使用字典映射:

    d = {('total', 'sum'): 'gross', ('total', 'count'): 'checkouts',
         ('quantity', 'sum'): 'items'}
    
    overview.columns = np.vectorize(d.get)(overview.columns)