Python 在透视表中添加列的总和(多索引)
我有df和df_轴,代码如下: 作为pd进口熊猫 将numpy作为np导入Python 在透视表中添加列的总和(多索引),python,pandas,pivot-table,Python,Pandas,Pivot Table,我有df和df_轴,代码如下: 作为pd进口熊猫 将numpy作为np导入 df = pd.DataFrame({"A": ["foo", "foo", "foo", "foo", "foo", "bar", "bar", "bar", "bar"]
df = pd.DataFrame({"A": ["foo", "foo", "foo", "foo", "foo",
"bar", "bar", "bar", "bar"],
"B": ["one", "one", "one", "two", "two",
"one", "one", "two", "two"],
"Year": [2019, 2019, 2019, 2019,
2019, 2019, 2020, 2020,
2020],
"Month": ["01", "02", "03", "04", "05", "06", "01", "02", "03"],
"Values": [2, 4, 5, 5, 6, 6, 8, 9, 9]})
df_pivot = pd.pivot_table(df, values='Values', index=['A', 'B'],
columns=['Year','Month'], aggfunc=np.sum, fill_value=0)
df_枢轴如下所示:
Year 2019 2020
Month 01 02 03 04 05 06 01 02 03
A B
bar one 0 0 0 0 0 6 8 0 0
two 0 0 0 0 0 0 0 9 9
foo one 2 4 5 0 0 0 0 0 0
two 0 0 0 5 6 0 0 0 0
现在我要做的是在df中添加三列:
2019财年、2019年年初至今、2020年年初至今
2019FY列应为“2019”项下所有值的总和
2019年年初至今列应为定义期间的“2019”项下所有值的总和,即,如果期间定义为04,则2019年年初至今应为2019年01/02/03/04的列总和
2020YTD列应为“2020”下所有值的总和
输出表应如下所示:
Year 2019 2019FY 2019YTD 2020 2020YTD
Month 01 02 03 04 05 06 01 02 03
A B
bar one 0 0 0 0 0 6 6 0 8 0 0 8
two 0 0 0 0 0 0 0 0 0 9 9 18
foo one 2 4 5 0 0 0 11 11 0 0 0 0
two 0 0 0 5 6 0 11 5 0 0 0 0
基本上,我想知道如何用给定的“月”对列求和,因为从这里我可以自己创建2019FY/2019YTD/2020YTD,而且将它们添加到数据透视表的特定时段(2019年底和2020年底)也很重要
可行吗
我到处找,但找不到如何做的例子
谢谢你的帮助
谢谢
Pawel每年都可以在自定义函数中创建新列,因此在输出中也可以在以下位置中创建
2020FY
列:
您可以使用:
df.columns.get_level_values()
df.index.get_level_values()
切片多索引行和列的语法。我建议将df的月份列从字符串“01”更改为整数值,这样可以更容易地使用<>运算符进行切片。
但是,如果需要使用字符串值的月份列名,则:
month_num = 4
df_pivot["2029YTD"] = df_pivot.loc[:, (df_pivot.columns.get_level_values(0) == 2019) &
(df_pivot.columns.get_level_values(1).astype(int) <= 4)].sum(axis=1)
df_pivot["2019FY"] = df_pivot.loc[:, df_pivot.columns.get_level_values(0) == 2019].sum(axis=1)
df_pivot["2020YTD"] = df_pivot.loc[:, df_pivot.columns.get_level_values(0) == 2020].sum(axis=1)
完成后,您可以使用以下方法调整列位置:
Year 2019 2020 2019YTD 2019FY 2020YTD
Month 01 02 03 04 05 06 01 02 03
A B
bar one 0 0 0 0 0 6 8 0 0 0 6 8
two 0 0 0 0 0 0 0 9 9 0 0 18
foo one 2 4 5 0 0 0 0 0 0 11 11 0
two 0 0 0 5 6 0 0 0 0 5 11 0
df_pivot = df_pivot.loc[:, [2019, "2019FY", "2019YTD", 2020, "2020YTD"]]
Year 2019 2019FY 2019YTD 2020 2020YTD
Month 01 02 03 04 05 06 01 02 03
A B
bar one 0 0 0 0 0 6 6 0 8 0 0 8
two 0 0 0 0 0 0 0 0 0 9 9 18
foo one 2 4 5 0 0 0 11 11 0 0 0 0
two 0 0 0 5 6 0 11 5 0 0 0 0
要获得类似于:
Year 2019 2020 2019YTD 2019FY 2020YTD
Month 01 02 03 04 05 06 01 02 03
A B
bar one 0 0 0 0 0 6 8 0 0 0 6 8
two 0 0 0 0 0 0 0 9 9 0 0 18
foo one 2 4 5 0 0 0 0 0 0 11 11 0
two 0 0 0 5 6 0 0 0 0 5 11 0
df_pivot = df_pivot.loc[:, [2019, "2019FY", "2019YTD", 2020, "2020YTD"]]
Year 2019 2019FY 2019YTD 2020 2020YTD
Month 01 02 03 04 05 06 01 02 03
A B
bar one 0 0 0 0 0 6 6 0 8 0 0 8
two 0 0 0 0 0 0 0 0 0 9 9 18
foo one 2 4 5 0 0 0 11 11 0 0 0 0
two 0 0 0 5 6 0 11 5 0 0 0 0
OP need
同样重要的是将它们添加到数据透视表的特定槽中(2019年底和2020年底的数据)。
Heya,在运行上述代码后格式化列位置应该是一项简单的任务,使用类似于:df_pivot.loc[:,[2019,“2019FY”,“2019YTD”,2020,“2020YTD]”的逻辑
您会得到预期的结果:)是的,我现在让它并排运行,我看不到任何问题。很好,完成了。试试看!:)好的,谢谢。唯一的问题是从1990年到2020年有几年的时间,然后是一个小问题使用您的解决方案。因为这是一个有点“手动”
,而不是dynamicDear-jezrael,我已经尝试运行您的代码,但打印后我没有收到相同的结果(df)。我收到了我自己的df,没有FY/YTD的附加列,您能建议吗?谢谢Pawel@PawełPoprawski-这意味着没有更像4
?因为s1
表示每年对所有行进行求和,s2
仅为前4列的fr求和。我使用了我的初始df,我假设我会收到与您相同的结果。您在我原来的df表中更改了几个月的任何格式吗?@PawełPoprawski-没有,但我使用的是pandas1.2.3
,YOUR版本不同?我更新了我的pandas,现在它可以工作了。非常感谢你!