我正在通过可汗学院的统计学课程作为我大学时代的一些复习,并且作为一种让我快速掌握大熊猫和其他科学Python的方法.
我有一张来自可汗学院的桌子:
| Undergraduate | Graduate | Total
-------------+---------------+----------+------
Straight A's | 240 | 60 | 300
-------------+---------------+----------+------
Not | 3,760 | 440 | 4,200
-------------+---------------+----------+------
Total | 4,000 | 500 | 4,500
Run Code Online (Sandbox Code Playgroud)
我想用pandas重新创建这个表.当然,我可以使用类似的东西创建一个DataFrame
"Graduate": {...},
"Undergraduate": {...},
"Total": {...},
Run Code Online (Sandbox Code Playgroud)
但这似乎是一种天真的方法,既快速挫败,又不是真正可扩展的.
我有这样的非总计部分:
df = pd.DataFrame(
{
"Undergraduate": {"Straight A's": 240, "Not": 3_760},
"Graduate": {"Straight A's": 60, "Not": 440},
}
)
df
Run Code Online (Sandbox Code Playgroud)
我一直在寻找并发现了一些很有前景的东西,比如:
df['Total'] = df.sum(axis=1)
Run Code Online (Sandbox Code Playgroud)
但我没有发现任何非常优雅的东西.
我确实找到了crosstab看起来应该做我想要的功能,但似乎为了做到这一点,我必须为所有这些值创建一个由1/0组成的数据帧,这看起来很愚蠢,因为我已经已经有一个聚合.
我发现一些方法似乎手动构建一个新的总计行,但似乎应该有一个更好的方法,如:
totals(df, rows=True, columns=True)
Run Code Online (Sandbox Code Playgroud)
或者其他的东西.
这是否存在于熊猫中,还是我必须拼凑自己的方法?
Arc*_*hie 26
或者分两步,使用.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)
Run Code Online (Sandbox Code Playgroud)
输出:
Graduate Undergraduate Total
Not 440 3760 4200
Straight A's 60 240 300
Total 500 4000 4500
Run Code Online (Sandbox Code Playgroud)
piR*_*red 11
append 和 assign这个答案的要点是提供一个在线而不是一个到位的解决方案.
append我append用来堆叠Series或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
Run Code Online (Sandbox Code Playgroud)
使用dropwith errors='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
Run Code Online (Sandbox Code Playgroud)
从使用的原始数据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
Run Code Online (Sandbox Code Playgroud)
玩具数据
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
Run Code Online (Sandbox Code Playgroud)