it-swarm.com.de

Python-Pandas: Wird die Reihenfolge bei Verwendung von groupby () und agg () beibehalten?

Ich habe die Funktion agg() von Pandas häufig verwendet, um Zusammenfassungsstatistiken für jede Spalte eines data.frame auszuführen. So würden Sie beispielsweise den Mittelwert und die Standardabweichung berechnen:

df = pd.DataFrame({'A': ['group1', 'group1', 'group2', 'group2', 'group3', 'group3'],
                   'B': [10, 12, 10, 25, 10, 12],
                   'C': [100, 102, 100, 250, 100, 102]})

>>> df
[output]
        A   B    C
0  group1  10  100
1  group1  12  102
2  group2  10  100
3  group2  25  250
4  group3  10  100
5  group3  12  102

In beiden Fällen spielt es keine Rolle, in welcher Reihenfolge einzelne Zeilen an die Funktion agg gesendet werden. Betrachten Sie jedoch das folgende Beispiel:

df.groupby('A').agg([np.mean, lambda x: x.iloc[1] ])

[output]

        mean  <lambda>  mean  <lambda>
A                                     
group1  11.0        12   101       102
group2  17.5        25   175       250
group3  11.0        12   101       102

In diesem Fall funktioniert das Lambda wie vorgesehen und gibt die zweite Zeile in jeder Gruppe aus. Es ist mir jedoch nicht gelungen, in der Pandas-Dokumentation irgendetwas zu finden, was impliziert, dass dies in allen Fällen garantiert wahr ist. Ich möchte agg() zusammen mit einer gewichteten Durchschnittsfunktion verwenden. Daher möchte ich sicherstellen, dass die Zeilen, die in die Funktion aufgenommen werden, in derselben Reihenfolge wie im ursprünglichen Datenrahmen angezeigt werden.

Weiß jemand, idealerweise über irgendwo in der Dokumentation oder im Pandas-Quellcode, ob dies garantiert der Fall ist?

23
BringMyCakeBack

Siehe diese Erweiterung Ausgabe

Die kurze Antwort lautet Ja, die Gruppe behält die Bestellungen wie übergeben. Sie können dies anhand Ihres Beispiels wie folgt belegen:

In [20]: df.sort_index(ascending=False).groupby('A').agg([np.mean, lambda x: x.iloc[1] ])
Out[20]: 
           B             C         
        mean <lambda> mean <lambda>
A                                  
group1  11.0       10  101      100
group2  17.5       10  175      100
group3  11.0       10  101      100

Dies gilt NICHT für das Resample, da dies einen monotonen Index erfordert (er wird mit einem nicht-monotonen Index arbeiten, wird ihn aber zuerst sortieren).

Es gibt eine sort=-Flagge, um sie zu gruppieren, dies bezieht sich jedoch auf die Sortierung der Gruppen selbst und nicht auf die Beobachtungen innerhalb einer Gruppe.

Zu Ihrer Information: df.groupby('A').nth(1) ist ein sicherer Weg, um den 2. Wert einer Gruppe zu erhalten (da Ihre Methode oben fehlschlägt, wenn eine Gruppe <2 Elemente hat)

17
Jeff

Das 0.19.1-Dokument von Panda sagt, "Groupby behält die Reihenfolge der Zeilen innerhalb jeder Gruppe" bei, so dass dieses Verhalten garantiert ist.

http://pandas.pydata.org/pandas-docs/stable/generated/pandas.DataFrame.groupby.html

7
Uwe Mayer

Um die Ordnung zu erhalten, müssen Sie .groupby(..., sort=False) übergeben. In Ihrem Fall ist die Gruppierungsspalte bereits sortiert, es macht also keinen Unterschied, aber im Allgemeinen muss das Flag sort=False verwendet werden:

 df.groupby('A', sort=False).agg([np.mean, lambda x: x.iloc[1] ])
0
Dima Lituiev

Sogar einfacher:

  import pandas as pd
  pd.pivot_table(df,index='A',aggfunc=(np.mean))

ausgabe:

            B    C
     A                
   group1  11.0  101
   group2  17.5  175
   group3  11.0  101
0
TinaW

Referenz: https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.groupby.html

Die API akzeptiert "SORT" als Argument.

Die Beschreibung für das SORT-Argument lautet wie folgt:

sort: bool, Standard-True-Sort-Gruppenschlüssel. Schalten Sie diese Option aus, um eine bessere Leistung zu erzielen. Beachten Sie, dass dies die Reihenfolge der Beobachtungen innerhalb jeder Gruppe nicht beeinflusst. Groupby behält die Reihenfolge der Zeilen innerhalb jeder Gruppe bei .

Somit ist klar, dass "Groupby" die Reihenfolge der Zeilen innerhalb jeder Gruppe beibehält.

0
Jigidi Sarnath