为了账号安全,请及时绑定邮箱和手机立即绑定

如何在 Pandas 中创建 sum 行和 sum 列?

如何在 Pandas 中创建 sum 行和 sum 列?

心有法竹 2021-08-24 16:45:33
我正在学习可汗学院的统计学课程,作为我大学时代的一点复习,也是让我快速了解 Pandas 和其他科学 Python 的一种方式。我有一张来自可汗学院的桌子,看起来像这样:             | Undergraduate | Graduate | Total-------------+---------------+----------+------Straight A's |           240 |       60 |   300-------------+---------------+----------+------Not          |         3,760 |      440 | 4,200-------------+---------------+----------+------Total        |         4,000 |      500 | 4,500我想使用熊猫重新创建这个表。当然,我可以使用类似的东西创建一个 DataFrame"Graduate": {...},"Undergraduate": {...},"Total": {...},但这似乎是一种天真的方法,既会很快失败,又不能真正扩展。我有表格的非总计部分,如下所示:df = pd.DataFrame(    {        "Undergraduate": {"Straight A's": 240, "Not": 3_760},        "Graduate": {"Straight A's": 60, "Not": 440},    })df我一直在寻找并发现了一些有希望的东西,例如:df['Total'] = df.sum(axis=1)但我没有发现任何非常优雅的东西。我确实找到了crosstab看起来应该做我想做的功能,但似乎为了做到这一点,我必须为所有这些值创建一个由 1/0 组成的数据框,这看起来很愚蠢,因为我已经已经有一个聚合。我发现了一些似乎手动构建新总计行的方法,但似乎应该有更好的方法,例如:totals(df, rows=True, columns=True)什么的。这是否存在于熊猫中,还是我必须拼凑出我自己的方法?
查看完整描述

3 回答

?
慕斯王

TA贡献1864条经验 获得超2个赞

或者分两步,.sum()按照您的建议使用该函数(这也可能更具可读性):


import pandas as pd


df = pd.DataFrame( {"Undergraduate": {"Straight A's": 240, "Not": 3_760},"Graduate": {"Straight A's": 60, "Not": 440},})


#Total sum per column: 

df.loc['Total',:]= df.sum(axis=0)


#Total sum per row: 

df.loc[:,'Total'] = df.sum(axis=1)

输出:


              Graduate  Undergraduate  Total

Not                440           3760   4200

Straight A's        60            240    300

Total              500           4000   4500


查看完整回答
反对 回复 2021-08-24
?
潇潇雨雨

TA贡献1833条经验 获得超4个赞

append 和 assign

这个答案的重点是提供在线而不是就地解决方案。


append

我append用来堆叠 aSeries或DataFrame垂直。它还创建了一个,copy以便我可以继续链接。


assign

我assign用来添加一列。然而,DataFrame我正在研究的是在下界空间之间。所以我lambda在assign参数中使用 a告诉Pandas将它应用到调用DataFrame.


df.append(df.sum().rename('Total')).assign(Total=lambda d: d.sum(1))


              Graduate  Undergraduate  Total

Not                440           3760   4200

Straight A's        60            240    300

Total              500           4000   4500

有趣的替代品

使用dropwitherrors='ignore'摆脱潜在的预先存在的Total行和列。


而且,还在排队。


def tc(d):

  return d.assign(Total=d.drop('Total', errors='ignore', axis=1).sum(1))


df.pipe(tc).T.pipe(tc).T


              Graduate  Undergraduate  Total

Not                440           3760   4200

Straight A's        60            240    300

Total              500           4000   4500


查看完整回答
反对 回复 2021-08-24
?
慕容3067478

TA贡献1773条经验 获得超3个赞

从使用的原始数据crosstab,如果只是基于您的输入,您只需要melt之前crosstab


s=df.reset_index().melt('index')

pd.crosstab(index=s['index'],columns=s.variable,values=s.value,aggfunc='sum',margins=True)

Out[33]: 

variable      Graduate  Undergraduate   All

index                                      

Not                440           3760  4200

Straight A's        60            240   300

All                500           4000  4500

玩具数据


df=pd.DataFrame({'c1':[1,2,2,3,4],'c2':[2,2,3,3,3],'c3':[1,2,3,4,5]}) 

# before `agg`, I think your input is the result after `groupby` 

df

Out[37]: 

   c1  c2  c3

0   1   2   1

1   2   2   2

2   2   3   3

3   3   3   4

4   4   3   5



pd.crosstab(df.c1,df.c2,df.c3,aggfunc='sum',margins

=True)

Out[38]: 

c2     2     3  All

c1                 

1    1.0   NaN    1

2    2.0   3.0    5

3    NaN   4.0    4

4    NaN   5.0    5

All  3.0  12.0   15


查看完整回答
反对 回复 2021-08-24
  • 3 回答
  • 0 关注
  • 459 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号