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

时间:2018-08-13 06:40:41

标签: python string pandas dataframe indexing

我有一个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

列名很奇怪,因为在我的实际代码中,此结果是通过以下分组操作从DataFrame df派生的。

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

我想重命名overview的列,所需结果如下:

                            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之后,列是按任意顺序排列的。 (由于重复的名称{​​{1}},应用rename似乎也很棘手。)

当前,我通过为'sum'使用OrderedDict来解决此问题,因此aggregators具有确定的列奇数。但是假设overview的创建不能固定在上游,那么我如何优雅地达到期望的结果呢?

1 个答案:

答案 0 :(得分:0)

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

pd.Index.map

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

列表理解+ f字符串

在Python 3.6及更高版本中,您可以使用格式化的字符串文字(PEP 498):

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

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

对于版本<3.6,可以使用str.formatstr.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)