如何向数据透视表分组添加过滤器?

How do I add a filter to a pivot table grouping?

提问人:hailthedawn 提问时间:11/8/2023 最后编辑:hailthedawn 更新时间:11/8/2023 访问量:48

问:

跟进:如何根据单独的类别类型对列求和,并保留零?

我使用“Id”作为一堆列的替身。其中之一是“日期”。这是我应用数据透视表方法后的数据帧。

同上 日期 A_Hours B_Hours
1 2/2/2022 4 4
2 2/4/2023 2 6
3 6/2/2023 3 0

但是,由于“Date”是我添加到带有“Id”的索引中的列之一,因此这里是为多个日期输入了多个小时的用户的数据帧。

同上 日期 A_Hours B_Hours
1 2/2/2022 4 4
2 2/3/2023 3 3
2 2/4/2023 2 6
3 6/2/2023 3 0

如何获取以下数据帧:

同上 2/3/2023_A_Hours 2/4/2023_B_Hours 6/2/2023_A_Hours 6/2/2023_B_Hours
1 0 0 0 0
2 3 3 2 6
3 0 0 3 0

请注意,在此之上放置了一个额外的过滤器 - Id 1 全为 0,因为在我们的结果数据帧中,我们不仅将单个 ID 的行合并为多个列,还只想计算 2023 年输入的小时数。(并不包括 2023 年 1 月 1 <的所有日期)

另请注意,这一次,我不想创建新的列名称“2/4/2023_B_Hours”。实际上,我更喜欢在“2/4/2023”下带有“A_hours”和“B_hours”的多级索引。StackOverflow 中的表不允许我这样格式化它。

Python Pandas 帧数据 透视表

评论

2赞 mozway 11/8/2023
您能否提供可重现的示例输入和匹配的预期输出?

答:

3赞 mozway 11/8/2023 #1

为了清楚起见,您应该提供一个可重现的示例。

假设这个,我们要考虑之后的日期(在 Id 3 中没有):2023-01-15

   Id        Date Category  Hours
0   1  2023-01-01        A      1   # this should be filtered out
1   1  2023-02-01        A      3
2   1  2023-02-01        B      4
3   2  2023-03-01        A      2
4   2  2023-03-01        B      6
5   3  2023-01-01        A      3   # this should be filtered out

您可以预先筛选行(例如使用 query),然后在透视后重新编制索引以添加缺少的 ID:

out = (df.query('Date > "2023-01-15"')
         .pivot_table(index='Id', columns='Category', values='Hours',
                      aggfunc='sum', fill_value=0,
                      margins=True, margins_name='Total')
         .add_suffix('_Hours')
         .drop('Total')
         .reindex(df['Id'].unique(), fill_value=0)
         .reset_index().rename_axis(columns=None)
      )

输出:

   Id  A_Hours  B_Hours  Total_Hours
0   1        3        4            7
1   2        2        6            8
2   3        0        0            0

评论

0赞 hailthedawn 11/8/2023
我刚刚添加了具体示例 - 但这看起来非常接近我想要的!谢谢!我在原来的问题中添加了一个注释 - 如果我想要一个多级索引,我该怎么办?
0赞 hailthedawn 11/8/2023
嘿,另外,我真的没有一列“Id”——它是用于标识唯一性的各种属性的集合。因此,当我写出列列表时,df['Id'].unique() 不起作用,因为 df['a', 'b', 'c'] 是一个数据帧,它说数据帧没有 .unique() 方法。在这种情况下,如何重新编制索引?
0赞 mozway 11/8/2023
然后df[your_cols].drop_duplicates().merge(output_of_pivot_table).fillna(0)
0赞 hailthedawn 11/9/2023
我试过这个,但这只是删除 2023 年 1 月 1 日之前的所有条目。我没有从您的示例输出中得到 id=3 行
0赞 mozway 11/9/2023
对不起,在how='left'merge ;)