Wie sortiere ich Pandas-Gruppen nach (mehreren/allen) Werten der Gruppen?Python

Python-Programme
Anonymous
 Wie sortiere ich Pandas-Gruppen nach (mehreren/allen) Werten der Gruppen?

Post by Anonymous »

Ich versuche, eine etwas komplizierte Gruppierungs- und Sortieroperation in Pandas durchzuführen. Ich möchte die Gruppen nach ihren Werten in aufsteigender Reihenfolge sortieren und bei Bedarf aufeinanderfolgende Werte für Tiebreaks verwenden.
Ich habe die ähnliche Frage „Pandas dataframe: How to sort groups by the früheste time of a group“ gelesen, die jedoch nur den Mindestwert in jeder Gruppe zum Sortieren verwendet und daher nicht den Fall behandelt, in dem zwei Gruppen denselben Mindestwert haben, sich aber in ihren anderen Werten unterscheiden.
Ebenso: Pandas gruppieren nach und sortieren dann Innerhalb von Gruppen geht es um die Sortierung innerhalb von Gruppen, nicht jedoch um die Sortierung zwischen Gruppen, die ich suche.
Betrachten Sie als konkretes Beispiel den folgenden Datenrahmen:

Code: Select all

df = pd.DataFrame({"pool": [5, 1, 9, 9, 5, 7, 7, 7, 9, 1, 5],
"arrival":[227, 60, 60, 88, 55, 55, 276, 46, 46, 35, 35]})
Ich möchte die Pools nach Ankunft sortieren, sodass der resultierende Datenrahmen wie folgt lautet:

Code: Select all

    pool  arrival
10     5       35
4      5       55
0      5      227
9      1       35
1      1       60
7      7       46
5      7       55
6      7      276
8      9       46
2      9       60
3      9       88
Ich konnte dies mit dem folgenden Code erreichen:

Code: Select all

# create column to indicate order of values in each group
df = df.sort_values("arrival")
df["order"] = df.groupby("pool")["arrival"].cumcount()

# use 'order' column to make columns for each arrival position
df["first"] = df["second"] = df["third"] = np.nan
df.loc[df["order"] == 0,"first"] = df.loc[df["order"] == 0,"arrival"]
df.loc[df["order"] == 1,"second"] = df.loc[df["order"] == 1,"arrival"]
df.loc[df["order"] == 2,"third"] = df.loc[df["order"] == 2,"arrival"]

# propagate the values to every member of the group
df[["first","second","third"]] = df.groupby("pool")[["first","second","third"]].transform("max")

# for groups with less than three members, fill the values with previous ones
df["second"] = df["second"].fillna(df["first"])
df["third"] = df["third"].fillna(df["second"])

# sort by the arrival position columns, then drop all the helper columns
df = df.sort_values(["first","second","third","pool"]).drop(columns=["first","second","third","order"])
Es funktioniert, ist aber nicht besonders skalierbar für Pools mit einer größeren Anzahl von Ankünften (20+). Ich bin davon überzeugt, dass es einen besseren Weg geben muss, aber ich weiß nicht, wie ich das machen soll.
Ich habe auch versucht, die Funktionen transform und nth zu kombinieren, wie unter „Verwenden von transform zusammen mit nth“ beschrieben, aber entgegen der akzeptierten Antwort auf diese Frage führt der Versuch, „nth“ an groupby.transform zu übergeben, zu ValueError: „nth“ is not a valid function name for transform(name) da nth gibt möglicherweise keinen oder mehrere Werte für eine bestimmte Gruppe zurück und transform kann diese Fälle nicht verarbeiten.

Quick Reply

Change Text Case: 
   
  • Similar Topics
    Replies
    Views
    Last post