使用数据透视 table (pandas) 中的小计行时保留索引部分(不同的列)
Keeping index section (different columns) when subtotal row in pivot table (pandas) is used
我正在尝试在数据透视表 table 中添加小计行(使用 pandas pd.pivot_table)。这是代码 table = pd.pivot_table(df, values= ['Quantity', 'Money', 'Cost'], index=['house','date', 'currency', 'family name'], columns=[], fill_value=0, aggfunc=np.sum)
。这是对应的输出(导出到excel):
然后,我尝试使用 house
作为参考来获取小计行。我按照 link 中所述的步骤进行操作,因此我使用 tablesum = table.groupby(level='house').sum()
创建了一个组。在我尝试连接 table
和 tablesum
数据帧之前,一切似乎都很好。这是我得到的(对于家庭 A):
基本上,我得到了table的索引中所述的四个类别(房子,日期,货币,姓氏)在一列(用逗号分隔) ).因此,即使我按房屋获得小计,我也失去了 pivot_table 分隔。所以,我的问题是:如何保留它(在不同列中维护 pivot_table 的索引)?
如有任何帮助,我们将不胜感激。
此致,
pd: 我也检查了这个 link Sub Total in pandas pivot Table 但这给了我另一种与字符串和数字相关的错误。
您可以在 goupby 之后使用转换来保持原始 table 布局。所以以下可能会给你想要的结果。
table.groupby(level='house').transform("sum")
如果这不是您想要的,请说明。
https://pandas.pydata.org/pandas-docs/stable/generated/pandas.DataFrame.transform.html
您可以创建具有 4
个级别的自定义 MultiIndex
,然后分配。
注意:第二层date
必须转成字符串,因为concat也是字符串,否则得到:
TypeError: Cannot compare type 'Timestamp' with type 'str'
df = pd.DataFrame({'house':list('aaaaabbbbb'),
'date':['2015-01-01'] * 3 + ['2015-01-02'] * 2 +
['2015-01-01'] * 3 +['2015-01-02'] * 2,
'currency':['USD'] * 3 + ['NK'] * 2 + ['USD'] * 3 +['NK'] * 2,
'Quantity':[1,3,5,7,1,0,7,2,3,9],
'Money':[5,3,6,9,2,4,7,2,3,9],
'Cost':[5,3,6,9,2,4,7,2,3,9],
'family name':list('aabbccaabb')})
print (df)
Cost Money Quantity currency date family name house
0 5 5 1 USD 2015-01-01 a a
1 3 3 3 USD 2015-01-01 a a
2 6 6 5 USD 2015-01-01 b a
3 9 9 7 NK 2015-01-02 b a
4 2 2 1 NK 2015-01-02 c a
5 4 4 0 USD 2015-01-01 c b
6 7 7 7 USD 2015-01-01 a b
7 2 2 2 USD 2015-01-01 a b
8 3 3 3 NK 2015-01-02 b b
9 9 9 9 NK 2015-01-02 b b
#convert only for subtotal - join with empty strings
df['date'] = df['date'].astype(str)
table = pd.pivot_table(df, values= ['Quantity', 'Money', 'Cost'],
index=['house','date', 'currency', 'family name'],
fill_value=0,
aggfunc=np.sum)
print (table)
Cost Money Quantity
house date currency family name
a 2015-01-01 USD a 8 8 4
b 6 6 5
2015-01-02 NK b 9 9 7
c 2 2 1
b 2015-01-01 USD a 9 9 9
c 4 4 0
2015-01-02 NK b 12 12 12
tablesum = table.groupby(level='house').sum()
tablesum.index = pd.MultiIndex.from_arrays([tablesum.index.get_level_values(0)+ '_sum',
len(tablesum.index) * [''],
len(tablesum.index) * [''],
len(tablesum.index) * ['']])
print (tablesum)
Cost Money Quantity
a_sum 25 25 17
b_sum 25 25 21
print (tablesum.index)
MultiIndex(levels=[['a_sum', 'b_sum'], [''], [''], ['']],
labels=[[0, 1], [0, 0], [0, 0], [0, 0]])
df = pd.concat([table, tablesum]).sort_index(level=0)
print (df)
Cost Money Quantity
house date currency family name
a 2015-01-01 USD a 8 8 4
b 6 6 5
2015-01-02 NK b 9 9 7
c 2 2 1
a_sum 25 25 17
b 2015-01-01 USD a 9 9 9
c 4 4 0
2015-01-02 NK b 12 12 12
b_sum 25 25 21
我正在尝试在数据透视表 table 中添加小计行(使用 pandas pd.pivot_table)。这是代码 table = pd.pivot_table(df, values= ['Quantity', 'Money', 'Cost'], index=['house','date', 'currency', 'family name'], columns=[], fill_value=0, aggfunc=np.sum)
。这是对应的输出(导出到excel):
然后,我尝试使用 house
作为参考来获取小计行。我按照 link tablesum = table.groupby(level='house').sum()
创建了一个组。在我尝试连接 table
和 tablesum
数据帧之前,一切似乎都很好。这是我得到的(对于家庭 A):
基本上,我得到了table的索引中所述的四个类别(房子,日期,货币,姓氏)在一列(用逗号分隔) ).因此,即使我按房屋获得小计,我也失去了 pivot_table 分隔。所以,我的问题是:如何保留它(在不同列中维护 pivot_table 的索引)?
如有任何帮助,我们将不胜感激。
此致,
pd: 我也检查了这个 link Sub Total in pandas pivot Table 但这给了我另一种与字符串和数字相关的错误。
您可以在 goupby 之后使用转换来保持原始 table 布局。所以以下可能会给你想要的结果。
table.groupby(level='house').transform("sum")
如果这不是您想要的,请说明。
https://pandas.pydata.org/pandas-docs/stable/generated/pandas.DataFrame.transform.html
您可以创建具有 4
个级别的自定义 MultiIndex
,然后分配。
注意:第二层date
必须转成字符串,因为concat也是字符串,否则得到:
TypeError: Cannot compare type 'Timestamp' with type 'str'
df = pd.DataFrame({'house':list('aaaaabbbbb'),
'date':['2015-01-01'] * 3 + ['2015-01-02'] * 2 +
['2015-01-01'] * 3 +['2015-01-02'] * 2,
'currency':['USD'] * 3 + ['NK'] * 2 + ['USD'] * 3 +['NK'] * 2,
'Quantity':[1,3,5,7,1,0,7,2,3,9],
'Money':[5,3,6,9,2,4,7,2,3,9],
'Cost':[5,3,6,9,2,4,7,2,3,9],
'family name':list('aabbccaabb')})
print (df)
Cost Money Quantity currency date family name house
0 5 5 1 USD 2015-01-01 a a
1 3 3 3 USD 2015-01-01 a a
2 6 6 5 USD 2015-01-01 b a
3 9 9 7 NK 2015-01-02 b a
4 2 2 1 NK 2015-01-02 c a
5 4 4 0 USD 2015-01-01 c b
6 7 7 7 USD 2015-01-01 a b
7 2 2 2 USD 2015-01-01 a b
8 3 3 3 NK 2015-01-02 b b
9 9 9 9 NK 2015-01-02 b b
#convert only for subtotal - join with empty strings
df['date'] = df['date'].astype(str)
table = pd.pivot_table(df, values= ['Quantity', 'Money', 'Cost'],
index=['house','date', 'currency', 'family name'],
fill_value=0,
aggfunc=np.sum)
print (table)
Cost Money Quantity
house date currency family name
a 2015-01-01 USD a 8 8 4
b 6 6 5
2015-01-02 NK b 9 9 7
c 2 2 1
b 2015-01-01 USD a 9 9 9
c 4 4 0
2015-01-02 NK b 12 12 12
tablesum = table.groupby(level='house').sum()
tablesum.index = pd.MultiIndex.from_arrays([tablesum.index.get_level_values(0)+ '_sum',
len(tablesum.index) * [''],
len(tablesum.index) * [''],
len(tablesum.index) * ['']])
print (tablesum)
Cost Money Quantity
a_sum 25 25 17
b_sum 25 25 21
print (tablesum.index)
MultiIndex(levels=[['a_sum', 'b_sum'], [''], [''], ['']],
labels=[[0, 1], [0, 0], [0, 0], [0, 0]])
df = pd.concat([table, tablesum]).sort_index(level=0)
print (df)
Cost Money Quantity
house date currency family name
a 2015-01-01 USD a 8 8 4
b 6 6 5
2015-01-02 NK b 9 9 7
c 2 2 1
a_sum 25 25 17
b 2015-01-01 USD a 9 9 9
c 4 4 0
2015-01-02 NK b 12 12 12
b_sum 25 25 21