我有一个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
的创建不能固定在上游,那么我如何优雅地达到期望的结果呢?
答案 0 :(得分:0)
您的数据框具有MultiIndex
作为列。您可以通过几种方法将其展平为常规索引:
overview.columns = overview.columns.map('_'.join)
在Python 3.6及更高版本中,您可以使用格式化的字符串文字(PEP 498):
overview.columns = [f'{i}_{j}' for i, j in overview.columns]
对于版本<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)