我有一个pivot_table
生成的DataFrame
,它的行有一个索引,列的行是MultiIndex
。 MultiIndex
的顶层是我在其上进行计算的数据的名称,第二层是该数据的DATE。这些值是这些计算的结果。看起来像这样:
Imgur link - my reputation not high enough to post inline images
我正在尝试按季度(例如Q42018)而不是每一天(数据的本机格式)对数据进行分组。
我发现this帖子使用PeriodIndex和GroupBy将日期的索引转换为四分之一/年的索引非常优雅并且最有意义。
问题是此解决方案适用于仅具有单个索引列的数据框。尝试执行此操作时遇到了问题,因为我的列是一个多索引,并且我不知道如何使它工作。到目前为止,这是我的尝试:
bt = cleaned2018_df.pivot_table(index='Broker',
values=['Interaction Id','Net Points'],
columns='Date',
aggfunc={'Interaction Id':pd.Series.nunique,
'Net Points':np.sum},
fill_value=0)
pidx = pd.PeriodIndex(bt.columns.levels[1], freq='Q')
broker_qtr_totals = bt.groupby(pidx, axis=1, level=1).sum()
如您所见,我正在获取MultiIndex
的第二级,其中包含所有日期,并通过PeriodIndex
函数运行它以获取四分之一索引。然后,我将该PeriodIndex
传递给groupby,并告诉它对列和日期所在的第二层进行操作。
这将返回ValueError
的{{1}}响应。而且我知道原因是因为我传递给GroupBy的Grouper and axis must be same length
值的长度为x,而数据帧的列轴的长度为2x(因为多重索引的第一级具有2个值)。
我只是迷上了如何正确地将其应用于整个索引的方法。我似乎无法从句法上找出答案,因此我想依靠社区的专业知识来确定是否有人可以帮助我。
如果我的解释不清楚,我们很乐意进一步澄清。预先谢谢你。
答案 0 :(得分:0)
我发现了这一点,并将发布答案,以防其他人遇到类似问题。我在正确地考虑问题,但是第一次尝试时遇到了一些错误。
长度错误是由于我将对MultiIndex
的第二级的显式引用传递给PeriodIndex
函数,然后将其传递给groupby。更好的解决方案是使用.get_level_values
函数,因为这考虑到了索引的多级性质,并根据更高级别的项目数返回适当的#个值。
例如-如果您的DataFrame的MultiIndex列具有2个级别-并且这2个级别每个包含3个值,则您的表将具有9个列,因为较低级别针对顶级中的每个值进行细分。我最初的解决方案是直接从第二个级别中获取这3个值,而不是全部9个。get_level_values
对此进行了纠正。
第二个问题是我只是将这个PeriodIndex
对象本身传递给了groupby。那会起作用,但随后它基本上只是忽略了MultiIndex的顶层。因此,您需要确保传递一个列表,其中包含原始的顶层和要分组的新的第二层。
更正的代码:
#use get_level_values instead of accessing levels directly
pIdx = pd.PeriodIndex(bt.columns.get_level_values(1), freq='Q')
# to maintain original grouping, pass in a list of your original top level,
# and the new second level
broker_qtr_totals = bt.groupby(by=[bt.columns.get_level_values(0), pidx],
axis=1).sum()
这有效