【问题标题】:GroupBy on a dataframe with multiindex columns using periodindex使用 periodindex 在具有多索引列的数据帧上进行 GroupBy
【发布时间】:2019-10-27 05:49:08
【问题描述】:

我有一个pivot_table 生成的DataFrame,它的行有一个索引,它的列有一个MultiIndexMultiIndex 的顶层是我正在运行计算的数据的名称,第二层是该数据的日期。这些值是这些计算的结果。它看起来像这样:

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,并告诉它对列和日期所在的第二层进行操作。

这将返回Grouper and axis must be same lengthValueError 响应。我知道原因是因为我传递给 GroupBy 的 pidx 值的长度为 x,而数据帧的列轴长度为 2x(因为多索引的第一级有 2 个值)。

我只是想知道如何正确地将其应用于整个索引。我似乎无法从语法上弄清楚,所以我想依靠社区的专业知识来看看是否有人可以帮助我。

如果我的解释不清楚,我很乐意进一步澄清。提前谢谢你。

【问题讨论】:

    标签: python pandas dataframe pivot-table pandas-groupby


    【解决方案1】:

    我想通了,我将发布答案,以防其他有类似问题的人在这里登陆。我正确地考虑了这个问题,但在我的第一次尝试中出现了一些错误。

    长度错误是由于我将对MultiIndex 的第二级的显式引用传递给PeriodIndex 函数,然后将其传递给groupby。更好的解决方案是使用.get_level_values 函数,因为这会考虑到索引的多级性质,并根据更高级别的项目数返回适当的值#。

    例如 - 如果您有一个包含 2 个级别的 MultiIndex 列的 DataFrame - 并且这 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()
    

    这行得通

    imgur link to dataframe image as my rep is too low

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-03-04
      • 1970-01-01
      • 2020-12-17
      • 2021-07-13
      • 2017-02-06
      • 1970-01-01
      • 1970-01-01
      • 2016-12-08
      相关资源
      最近更新 更多