Wenn ich einen Datenrahmen mit Spalten habe, die denselben Namen enthalten, gibt es eine Möglichkeit, die Spalten mit demselben Namen mit einer Funktion (d. H. Summe) zu kombinieren?

Zum Beispiel mit:

In [186]:

df["NY-WEB01"].head()
Out[186]:
                NY-WEB01    NY-WEB01
DateTime        
2012-10-18 16:00:00  5.6     2.8
2012-10-18 17:00:00  18.6    12.0
2012-10-18 18:00:00  18.4    12.0
2012-10-18 19:00:00  18.2    12.0
2012-10-18 20:00:00  19.2    12.0

Wie kann ich die NY-WEB01-Spalten reduzieren (es gibt eine Reihe doppelter Spalten, nicht nur NY-WEB01), indem ich jede Zeile summiere, in der der Spaltenname identisch ist?

24
Kyle Brandt 26 Okt. 2012 im 03:19

3 Antworten

Beste Antwort

Ich glaube, das macht das, wonach Sie suchen:

df.groupby(lambda x:x, axis=1).sum()

Alternativ zwischen 3% und 15% schneller, abhängig von der Länge des df:

df.groupby(df.columns, axis=1).sum()

BEARBEITEN: Um dies über die Summen hinaus zu erweitern, verwenden Sie .agg() (kurz für .aggregate()):

df.groupby(df.columns, axis=1).agg(numpy.max)
24
meteore 26 Okt. 2012 im 15:50

V0.20 + Antwort: GroupBy mit den Argumenten level und axis

Sie brauchen hier kein Lambda und müssen auch nicht explizit df.columns abfragen. groupby akzeptiert ein { {X2}} Argument, das Sie in Verbindung mit dem axis Argument angeben können. Das ist sauberer, IMO.

# Setup
np.random.seed(0)
df = pd.DataFrame(np.random.choice(50, (5, 5)), columns=list('AABBB'))
df

    A   A   B   B   B
0  44  47   0   3   3
1  39   9  19  21  36
2  23   6  24  24  12
3   1  38  39  23  46
4  24  17  37  25  13
df.groupby(level=0, axis=1).sum()

    A    B
0  91    6
1  48   76
2  29   60
3  39  108
4  41   75

Behandlung von MultiIndex Spalten

Ein weiterer zu berücksichtigender Fall ist der Umgang mit MultiIndex Spalten. Erwägen

df.columns = pd.MultiIndex.from_arrays([['one']*3 + ['two']*2, df.columns])
df
  one         two    
    A   A   B   B   B
0  44  47   0   3   3
1  39   9  19  21  36
2  23   6  24  24  12
3   1  38  39  23  46
4  24  17  37  25  13

Verwenden Sie, um eine Aggregation über die oberen Ebenen durchzuführen

df.groupby(level=1, axis=1).sum()

    A    B
0  91    6
1  48   76
2  29   60
3  39  108
4  41   75

Oder, wenn nur nach oberer Ebene aggregiert wird, verwenden Sie

df.groupby(level=[0, 1], axis=1).sum()

  one     two
    A   B   B
0  91   0   6
1  48  19  57
2  29  24  36
3  39  39  69
4  41  37  38

Alternative Interpretation: Löschen doppelter Spalten

Wenn Sie hierher gekommen sind, um herauszufinden, wie Sie einfach doppelte Spalten löschen können (ohne eine Aggregation durchzuführen), verwenden Sie Index.duplicated:

df.loc[:,~df.columns.duplicated()]

    A   B
0  44   0
1  39  19
2  23  24
3   1  39
4  24  37

Um die letzten zu behalten, geben Sie keep='last' an (Standard ist 'first').

df.loc[:,~df.columns.duplicated(keep='last')]

    A   B
0  47   3
1   9  36
2   6  12
3  38  46
4  17  13

Die groupby Alternativen für die beiden oben genannten Lösungen sind df.groupby(level=0, axis=1).first() bzw. ... .last().

7
cs95 30 Mai 2019 im 04:17

Hier ist eine einfachere Lösung für gängige Aggregationsfunktionen wie sum, mean, median, max, min, std möglich. Verwenden Sie nur Parameter { {X6}} für die Arbeit mit Spalten und level:

#coldspeed samples
np.random.seed(0)
df = pd.DataFrame(np.random.choice(50, (5, 5)), columns=list('AABBB'))
print (df)

print (df.sum(axis=1, level=0))
    A    B
0  91    6
1  48   76
2  29   60
3  39  108
4  41   75

df.columns = pd.MultiIndex.from_arrays([['one']*3 + ['two']*2, df.columns])

print (df.sum(axis=1, level=1))
    A    B
0  91    6
1  48   76
2  29   60
3  39  108
4  41   75

print (df.sum(axis=1, level=[0,1]))
  one     two
    A   B   B
0  91   0   6
1  48  19  57
2  29  24  36
3  39  39  69
4  41  37  38

Ähnlich funktioniert es für den Index, dann verwenden Sie stattdessen axis=0 axis=1:

np.random.seed(0)
df = pd.DataFrame(np.random.choice(50, (5, 5)), columns=list('ABCDE'), index=list('aabbc'))
print (df)
    A   B   C   D   E
a  44  47   0   3   3
a  39   9  19  21  36
b  23   6  24  24  12
b   1  38  39  23  46
c  24  17  37  25  13

print (df.min(axis=0, level=0))
    A   B   C   D   E
a  39   9   0   3   3
b   1   6  24  23  12
c  24  17  37  25  13

df.index = pd.MultiIndex.from_arrays([['bar']*3 + ['foo']*2, df.index])

print (df.mean(axis=0, level=1))
      A     B     C     D     E
a  41.5  28.0   9.5  12.0  19.5
b  12.0  22.0  31.5  23.5  29.0
c  24.0  17.0  37.0  25.0  13.0

print (df.max(axis=0, level=[0,1]))
        A   B   C   D   E
bar a  44  47  19  21  36
    b  23   6  24  24  12
foo b   1  38  39  23  46
    c  24  17  37  25  13

Verwenden Sie bei Bedarf andere Funktionen wie first, last, size, count. Verwenden Sie Coldspeed-Antwort

2
jezrael 5 Apr. 2019 im 10:54