Pandas:如何包含多个数据透视表的所有列和所有索引 table
Pandas: How to include all columns and all indexes for multiple pivot table
我正在尝试为来自以下数据框 (df
) 的不同位置创建枢轴 tables:
Location
Category
Status
Price
1
Furniture
New
0
1
Furniture
Old
2
Office Supplies
New
0
1
Furniture
New
0
1
Office Supplies
New
0
1
Office Supplies
Old
0
首先,我使用代码过滤了数据帧以分离位置 1 和 2:
df1 = df[df['Location'] == 1]
df2 = df[df['Location'] == 2]
接下来我使用了标准的 pandas pivot table 函数:
pd.pivot_table(df1, values='Price', index='Status', columns='Category', aggfunc=np.sum)
pd.pivot_table(df2, values='Price', index='Status', columns='Category', aggfunc=np.sum)
所以我有以下两个枢轴 table 作为输出:
位置 1:
Status
Furniture
Office Supplies
New
0
0
Old
0
位置 2:
Status
Office Supplies
New
0
但是,我希望位置 2 的枢轴 table 包含所有可能的类别和状态,如果不存在则为 0。总而言之,我想要位置 2 的以下枢轴 table:
位置 2:
Status
Furniture
Office Supplies
New
[=18=]
0
Old
[=18=]
[=18=]
我已经遍历了 pivot_table() 函数的所有选项,但到目前为止还没有找到解决这个问题的方法。
您可以在拆分 Location
之前创建枢轴 table。
- 设置索引
index=['Location', 'Status']
- 传递参数
dropna=False
以允许所有类别显示所有 Location
和所有 Status
,即使是空的。 (默认是隐藏空条目)。
- 传递参数
fill_value=0
以将 NaN
值填充为 0
然后通过.loc
从支点table定位Location
,如下:
df_out = pd.pivot_table(df,
values='Price',
index=['Location', 'Status'],
columns='Category',
aggfunc=np.sum,
dropna=False,
fill_value=0)
结果:
print(df_out)
Category Furniture Office Supplies
Location Status
1 New 200 300
Old 50 150
2 New 0 200
Old 0 0
那么,为了得到Location
2的枢轴table,可以使用.loc
,如下:
df2 = df_out.loc[2]
输出:
print(df2)
Category Furniture Office Supplies
Status
New 0 200
Old 0 0
编辑(添加总计和小计)
如果您还想包括 总计(对于所有 Location
)和 小计(对于每个 Location
),你也可以这样做,如下:
- 传递参数
margins=True
和 margins_name='Total'
来设置 Total 的边距(所有 Location
的总计)
- 在
pd.pivot_table
之后链接命令 fillna(0, downcast='infer')
。这是为了处理 pd.pivot_table
的 故障 / 错误 保证金总额仍将显示 NaN
空条目(例如 Location=2
Status='Old'
在这种情况下)即使指定了 fill_value=0
参数。
df_out = pd.pivot_table(df,
values='Price',
index=['Location', 'Status'],
columns='Category',
aggfunc=np.sum,
dropna=False,
fill_value=0,
margins=True,
margins_name='Total'
).fillna(0, downcast='infer')
结果
print(df_out)
Category Furniture Office Supplies Total
Location Status
1 New 200 300 500
Old 50 150 200
2 New 0 200 200
Old 0 0 0
Total 250 650 900
然后,要添加 小计(对于每个 Location
),我们进一步使用:
(pd.concat([df_out,
df_out.query('Location != "Total"')
.groupby(level=0).sum()
.assign(Status='Sub-total')
.set_index('Status', append=True)])
.sort_index())
结果:
Category Furniture Office Supplies Total
Location Status
1 New 200 300 500
Old 50 150 200
Sub-total 250 450 700
2 New 0 200 200
Old 0 0 0
Sub-total 0 200 200
Total 250 650 900
我正在尝试为来自以下数据框 (df
) 的不同位置创建枢轴 tables:
Location | Category | Status | Price |
---|---|---|---|
1 | Furniture | New | 0 |
1 | Furniture | Old | |
2 | Office Supplies | New | 0 |
1 | Furniture | New | 0 |
1 | Office Supplies | New | 0 |
1 | Office Supplies | Old | 0 |
首先,我使用代码过滤了数据帧以分离位置 1 和 2:
df1 = df[df['Location'] == 1]
df2 = df[df['Location'] == 2]
接下来我使用了标准的 pandas pivot table 函数:
pd.pivot_table(df1, values='Price', index='Status', columns='Category', aggfunc=np.sum)
pd.pivot_table(df2, values='Price', index='Status', columns='Category', aggfunc=np.sum)
所以我有以下两个枢轴 table 作为输出:
位置 1:
Status | Furniture | Office Supplies |
---|---|---|
New | 0 | 0 |
Old | 0 |
位置 2:
Status | Office Supplies |
---|---|
New | 0 |
但是,我希望位置 2 的枢轴 table 包含所有可能的类别和状态,如果不存在则为 0。总而言之,我想要位置 2 的以下枢轴 table:
位置 2:
Status | Furniture | Office Supplies |
---|---|---|
New | [=18=] | 0 |
Old | [=18=] | [=18=] |
我已经遍历了 pivot_table() 函数的所有选项,但到目前为止还没有找到解决这个问题的方法。
您可以在拆分 Location
之前创建枢轴 table。
- 设置索引
index=['Location', 'Status']
- 传递参数
dropna=False
以允许所有类别显示所有Location
和所有Status
,即使是空的。 (默认是隐藏空条目)。 - 传递参数
fill_value=0
以将NaN
值填充为0
然后通过.loc
从支点table定位Location
,如下:
df_out = pd.pivot_table(df,
values='Price',
index=['Location', 'Status'],
columns='Category',
aggfunc=np.sum,
dropna=False,
fill_value=0)
结果:
print(df_out)
Category Furniture Office Supplies
Location Status
1 New 200 300
Old 50 150
2 New 0 200
Old 0 0
那么,为了得到Location
2的枢轴table,可以使用.loc
,如下:
df2 = df_out.loc[2]
输出:
print(df2)
Category Furniture Office Supplies
Status
New 0 200
Old 0 0
编辑(添加总计和小计)
如果您还想包括 总计(对于所有 Location
)和 小计(对于每个 Location
),你也可以这样做,如下:
- 传递参数
margins=True
和margins_name='Total'
来设置 Total 的边距(所有Location
的总计) - 在
pd.pivot_table
之后链接命令fillna(0, downcast='infer')
。这是为了处理pd.pivot_table
的 故障 / 错误 保证金总额仍将显示NaN
空条目(例如Location=2
Status='Old'
在这种情况下)即使指定了fill_value=0
参数。
df_out = pd.pivot_table(df,
values='Price',
index=['Location', 'Status'],
columns='Category',
aggfunc=np.sum,
dropna=False,
fill_value=0,
margins=True,
margins_name='Total'
).fillna(0, downcast='infer')
结果
print(df_out)
Category Furniture Office Supplies Total
Location Status
1 New 200 300 500
Old 50 150 200
2 New 0 200 200
Old 0 0 0
Total 250 650 900
然后,要添加 小计(对于每个 Location
),我们进一步使用:
(pd.concat([df_out,
df_out.query('Location != "Total"')
.groupby(level=0).sum()
.assign(Status='Sub-total')
.set_index('Status', append=True)])
.sort_index())
结果:
Category Furniture Office Supplies Total
Location Status
1 New 200 300 500
Old 50 150 200
Sub-total 250 450 700
2 New 0 200 200
Old 0 0 0
Sub-total 0 200 200
Total 250 650 900