熊猫数据框总行


73

我有一个数据框,类似:

     foo  bar  qux
0    a    1    3.14
1    b    3    2.72
2    c    2    1.62
3    d    9    1.41
4    e    3    0.58

我想在数据框的末尾添加一个“总计”行:

     foo  bar  qux
0    a    1    3.14
1    b    3    2.72
2    c    2    1.62
3    d    9    1.41
4    e    3    0.58
5    tot  15   9.47

我尝试使用该sum命令,但最终得到一个Series,尽管可以将其转换回Dataframe,但它不维护数据类型:

tot_row = pd.DataFrame(df.sum()).T
tot_row['foo'] = 'tot'
tot_row.dtypes:
     foo    object
     bar    object
     qux    object

我想维护原始数据帧中的数据类型,因为我需要对总行应用其他操作,例如:

baz = 2*tot_row['qux'] + 3*tot_row['bar']

18
尝试df.loc['Total']= df.sum(),从此链接
Kevin Zhu

Answers:


50

将总计行附加到

df.append(df.sum(numeric_only=True), ignore_index=True)

仅当您有一列字符串或对象时,才需要进行转换。

这是一个脆弱的解决方案,因此我建议仍然坚持对数据框进行操作。例如。

baz = 2*df['qux'].sum() + 3*df['bar'].sum()

这不会保留原始数据类型。所有列都将转换为对象(按其外观是字符串)。
丹尼尔(Daniel)

抱歉,您是对的,我没有使用一列字符串对其进行检查。现在更新。
jmz 2014年

这几乎是正确的。唯一的问题是数据类型还没有完全保留。整数转换为浮点数。幸运的是,我认为这对我来说不是问题。如果今天没有人发布替代方案,我将接受此解决方案。
丹尼尔(Daniel)

再次更新以防止汇总的数值数据发生任何类型的更改。现在,字符串将显示np.nan在总行中。
jmz 2014年

这很棒。为我工作,谢谢。但是,此后如何将索引改回我的指定列表?
鲍文刘

34
df.loc["Total"] = df.sum()

为我工作,我发现它更容易记住。我想念什么吗?可能在早期版本中是不可能的。

我实际上只想临时添加总行。永久添加它有利于显示,但使以后的计算变得麻烦。

刚发现

df.append(df.sum().rename('Total'))

这会在Jupyter笔记本中打印出我想要的内容,并且看起来不影响df本身。


1
真好!与R非常相似,快速干净!:-)
伊万·卡拉斯科

19

更新:2020

要同时获取行和列:

import numpy as np
import pandas as pd


df = pd.DataFrame({'a': [10,20],'b':[100,200],'c': ['a','b']})

df.loc['Column_Total']= df.sum(numeric_only=True, axis=0)
df.loc[:,'Row_Total'] = df.sum(numeric_only=True, axis=1)

print(df)


                 a      b    c  Row_Total
0             10.0  100.0    a      110.0
1             20.0  200.0    b      220.0
Column_Total  30.0  300.0  NaN      330.0

15

使用DataFrame.pivot_tablemargins=True

import pandas as pd
data = [('a',1,3.14),('b',3,2.72),('c',2,1.62),('d',9,1.41),('e',3,.58)]
df = pd.DataFrame(data, columns=('foo', 'bar', 'qux'))

原件df

  foo  bar   qux
0   a    1  3.14
1   b    3  2.72
2   c    2  1.62
3   d    9  1.41
4   e    3  0.58

由于pivot_table需要某种分组(不带index参数,它将引发ValueError: No group keys passed!),并且您的原始索引是虚空的,因此我们将使用foo列:

df.pivot_table(index='foo',
               margins=True,
               margins_name='total',  # defaults to 'All'
               aggfunc=sum)

瞧!

       bar   qux
foo             
a        1  3.14
b        3  2.72
c        2  1.62
d        9  1.41
e        3  0.58
total   18  9.47

如何将总和限制为仅特定列?
FabioSpaghetti

这对我有用,但是当我在命令提示符下再次编写df时,它会打印旧的df,而我看不到总和。也不会在Excel文件中写入总数
FabioSpaghetti

7

替代方法(已在Pandas 0.18.1上验证):

import numpy as np
total = df.apply(np.sum)
total['foo'] = 'tot'
df.append(pd.DataFrame(total.values, index=total.keys()).T, ignore_index=True)

结果:

   foo   bar   qux
0    a     1  3.14
1    b     3  2.72
2    c     2  1.62
3    d     9  1.41
4    e     3  0.58
5  tot    18  9.47

4

基于JMZ的答案

df.append(df.sum(numeric_only=True), ignore_index=True)

如果要继续使用当前索引,可以使用.rename()命名和系列,如下所示:

df.append(df.sum().rename('Total'))

这将在表格底部添加一行。


3

以下帮助我将列总计和行总计添加到数据框。

假设dft1是您的原始数据帧...现在,通过以下步骤添加列总计和行总计。

from io import StringIO
import pandas as pd

#create dataframe string
dfstr = StringIO(u"""
a;b;c
1;1;1
2;2;2
3;3;3
4;4;4
5;5;5
""")

#create dataframe dft1 from string
dft1 = pd.read_csv(dfstr, sep=";")

## add a column total to dft1
dft1['Total'] = dft1.sum(axis=1)

## add a row total to dft1 with the following steps

sum_row = dft1.sum(axis=0) #get sum_row first
dft1_sum=pd.DataFrame(data=sum_row).T #change it to a dataframe

dft1_sum=dft1_sum.reindex(columns=dft1.columns) #line up the col index to dft1
dft1_sum.index = ['row_total'] #change row index to row_total

dft1.append(dft1_sum) # append the row to dft1

3

这是我的方法,即通过转置并结合使用lambda函数和使用assign方法。这对我来说很简单。

df.T.assign(GrandTotal = lambda x: x.sum(axis=1)).T

0

基于Matthias Kauer的回答。

要添加总计:

df.loc["Row_Total"] = df.sum()

要添加总计列,

df.loc[:,"Column_Total"] = df.sum(axis=1)
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.