【问题标题】:Pandas dataframe total row熊猫数据框总行
【发布时间】:2022-03-14 18:33:23
【问题描述】:

我有一个数据框,类似于:

     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  total  18   9.47

我尝试使用sum 命令,但最终得到了一个系列,虽然我可以转换回数据框,但它不维护数据类型:

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']

【问题讨论】:

  • 试试df.loc['Total']= df.sum(),引用自此link

标签: python pandas


【解决方案1】:

添加一个总计行

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

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

这是一个有点脆弱的解决方案,所以我建议坚持对数据帧进行操作。例如。

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

【讨论】:

  • 这不维护原始数据类型;所有列都转换为对象(从外观上看是字符串)。
  • 对不起,你是对的,我没有用一列字符串检查它。现已更新。
  • 这几乎是正确的。唯一的问题是数据类型没有完全保留。整数转换为浮点数。幸运的是,我认为这对我来说不是问题。如果今天没有人发布替代方案,我将接受此解决方案。
  • 再次更新以防止汇总数值数据的任何类型更改。字符串现在将在总行中显示为 np.nan
  • 但这不会改变DataFrame的实际数据吗?所以例如df.describe() 会取数据加上数据的总和吗?
【解决方案2】:
df.loc["Total"] = df.sum()

对我有用,我发现它更容易记住。我错过了什么吗? 在早期版本中可能是不可能的。

我实际上只想暂时添加总行。 永久添加它有利于显示,但在进一步计算时会很麻烦。

刚刚找到

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

这会在 Jupyter 笔记本中打印我想要的内容,并且似乎没有改变 df 本身。

【讨论】:

  • 不错!与 R 非常相似,又快又干净! :-)
  • 这对我有用,非常简单。赞成:)
【解决方案3】:

新方法

获取行和列的总数:

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

【讨论】:

  • 这应该是内置函数^^]
【解决方案4】:

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

【讨论】:

  • 我怎样才能将总和限制在特定的列?
  • 这对我有用,但是当我在命令提示符下再次编写 df 时,它会打印旧的 df 并且我看不到总和。它也不会在 Excel 文件中写入总数
【解决方案5】:

替代方式(在 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

【讨论】:

    【解决方案6】:

    基于 JMZ 答案

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

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

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

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

    【讨论】:

      【解决方案7】:

      基于 Matthias Kauer 的回答。

      添加行总数:

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

      要添加列总数,

      df.loc[:,"Column_Total"] = df.sum(axis=1)
      

      【讨论】:

        【解决方案8】:

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

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

        【讨论】:

          【解决方案9】:

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

          假设 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
          

          【讨论】:

            【解决方案10】:

            实际上,所有提出的解决方案都会使原始 DataFrame 无法用于任何进一步的分析,并且会使后续计算无效,这将容易被忽视并且可能导致错误的结果

            这是因为您在数据中添加了一行,Pandas 无法将其与额外的数据行区分开来。

            示例:

            import pandas as pd
            data = [1, 5, 6, 8, 9]
            df = pd.DataFrame(data)
            df
            df.describe()
            

            产量

            0
            0 1
            1 5
            2 6
            3 8
            4 9
            0
            count 5
            mean 5.8
            std 3.11448
            min 1
            25% 5
            50% 6
            75% 8
            max 9

            之后

            df.loc['Totals']= df.sum(numeric_only=True, axis=0)
            

            数据框看起来像这样

            0
            0 1
            1 5
            2 6
            3 8
            4 9
            Totals 29

            这看起来不错,但新行被视为附加数据项,因此df.describe 将产生错误结果:

            0
            count 6
            mean 9.66667
            std 9.87252
            min 1
            25% 5.25
            50% 7
            75% 8.75
            max 29

            所以:小心!仅在对数据进行所有其他分析或处理 DataFrame 副本后应用此功能!

            【讨论】:

              猜你喜欢
              • 2021-01-22
              • 2017-05-31
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2014-10-03
              • 1970-01-01
              • 2021-11-11
              相关资源
              最近更新 更多