Pandas Datenrahmen Gesamtzeile

73

Ich habe einen Datenrahmen, so etwas wie:

     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

und ich möchte am Ende des Datenrahmens eine 'Gesamt'-Zeile hinzufügen:

     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

Ich habe versucht, den sumBefehl zu verwenden, aber am Ende habe ich eine Serie, die zwar wieder in einen Datenrahmen konvertiert werden kann, aber die Datentypen nicht verwaltet:

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

Ich möchte die Datentypen aus dem ursprünglichen Datenrahmen beibehalten, da ich andere Operationen auf die gesamte Zeile anwenden muss, wie zum Beispiel:

baz = 2*tot_row['qux'] + 3*tot_row['bar']
Daniel
quelle
18
Versuchen Sie df.loc['Total']= df.sum(), von diesem Link
Kevin Zhu

Antworten:

50

Fügen Sie eine Summenzeile mit hinzu

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

Die Konvertierung ist nur erforderlich, wenn Sie eine Spalte mit Zeichenfolgen oder Objekten haben.

Es ist eine etwas fragile Lösung, daher würde ich empfehlen, sich an die Vorgänge im Datenrahmen zu halten. z.B.

baz = 2*df['qux'].sum() + 3*df['bar'].sum()
jmz
quelle
Dadurch werden die ursprünglichen Datentypen nicht beibehalten. Alle Spalten werden in Objekte konvertiert (Zeichenfolgen, wie es aussieht).
Daniel
Entschuldigung, Sie haben Recht, ich habe es nicht mit einer Spalte von Zeichenfolgen überprüft. Jetzt aktualisiert.
JMZ
Das ist fast richtig. Das einzige ist, dass die Datentypen nicht ganz erhalten bleiben; Ints werden in Floats umgewandelt. Zum Glück glaube ich nicht, dass dies ein Problem für mich sein wird. Ich werde diese Lösung akzeptieren, wenn heute niemand eine Alternative veröffentlicht.
Daniel
Erneut aktualisiert, um Typänderungen von summierten numerischen Daten zu verhindern. Zeichenfolgen werden jetzt wie np.nanin der gesamten Zeile angezeigt.
JMZ
Das ist toll. Hat für mich gearbeitet, danke. Aber wie kann ich den Index danach wieder in meine festgelegte Liste ändern?
Bowen Liu
34
df.loc["Total"] = df.sum()

funktioniert für mich und ich finde es leichter, mich zu erinnern. Vermisse ich etwas In früheren Versionen war das wahrscheinlich nicht möglich.

Ich möchte die gesamte Zeile jedoch nur vorübergehend hinzufügen. Das dauerhafte Hinzufügen ist gut für die Anzeige, macht es jedoch zu einem Aufwand für weitere Berechnungen.

Gerade gefunden

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

Dies druckt, was ich in einem Jupyter-Notizbuch möchte, und scheint den df selbst unberührt zu lassen.

Matthias Kauer
quelle
1
nett! sehr ähnlich zu R, schnell und sauber! :-)
Ivan Carrasco Quiroz
19

Update: 2020

So erhalten Sie sowohl die Zeilen- als auch die Spaltensumme:

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
Bhishan Poudel
quelle
15

Verwendung DataFrame.pivot_tablemit margins=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'))

Original 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

Da pivot_tableeine Gruppierung erforderlich ist (ohne das indexArgument ValueError: No group keys passed!wird ein a ausgelöst) und Ihr ursprünglicher Index leer ist, verwenden wir die folgende fooSpalte:

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

Voilà!

       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
rmschne
quelle
Wie kann ich die Summe nur bestimmten Spalten zuordnen?
FabioSpaghetti
Dies hat bei mir funktioniert, aber wenn ich df erneut in die Eingabeaufforderung schreibe, wird das alte df gedruckt und die Summe wird nicht angezeigt. auch schreibt es nicht die Summe in Excel-Datei
FabioSpaghetti
7

Alternativer Weg (verifiziert auf 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)

Ergebnis:

   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
Frishrash
quelle
4

Aufbauend auf der Antwort von JMZ

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

Wenn Sie Ihren aktuellen Index weiterhin verwenden möchten, können Sie die Summenreihe mit .rename () wie folgt benennen:

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

Dadurch wird am Ende der Tabelle eine Zeile hinzugefügt.

Pedro Moisés Camacho Ureña
quelle
3

Das Folgende hat mir geholfen, einem Datenrahmen eine Spalten- und eine Zeilensumme hinzuzufügen.

Angenommen, dft1 ist Ihr ursprünglicher Datenrahmen. Fügen Sie nun mit den folgenden Schritten eine Spaltensumme und eine Zeilensumme hinzu.

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
ihightower
quelle
3

Dies ist die Art und Weise, wie ich es mache, indem ich die Zuweisungsmethode in Kombination mit einer Lambda-Funktion transponiere und verwende. Das macht es mir einfach.

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

Aufbauend auf der Antwort von Matthias Kauer.

So fügen Sie die Zeilensumme hinzu:

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

Um die Spaltensumme hinzuzufügen,

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