Ich arbeite mit ein paar Daten und würde gerne ziehendas Maximum für eine bestimmte Spalte, gruppiert nach einer anderen Spalte. Ich möchte jedoch bestimmte Zeilen aus der maximalen Berechnung ausschließen, die auf einer anderen Spalte basieren.
Beispiel:
df = pd.DataFrame({"Col1":["A","A","A","B","B","B","B"],
"Col2":["Build","Plan","Other","Test","Build","Other","Buy"],
"Col3":[2,5,17,5,13,12,12]})
Ich möchte das Maximum von Col3 erhalten, gruppiert nach Col1, wobei alle Zeilen ausgeschlossen werden, die in Col2 "Other" enthalten. Das Maximum von Col3 für "A" sollte also 5 sein, nicht 17.
Ich konnte das Maximum von Col3 nach Col1 gruppieren. df["new"] = df.groupby(["Col1"])["Col3"].transform(max)
Dies gibt mir jedoch einen Wert von 17 für A.
Ich habe mich in anderen Threads umgesehen:
x = df1.groupby(["Col1"])
x2 = x.apply(lambda g: g[g["Col2"] != "Other"])
und dies scheint mir nahe zu kommen (es hat die Daten nach Col1 gruppiert und die Zeilen wurden basierend auf Col2 entfernt). Ich finde jedoch keinen Weg mehr, das Maximum von Col3 basierend auf Col1 zu erreichen.
Am besten konnte ich verwenden: x2["Col3"].max()
um das Maximum von Col3 zu erhalten, nachdem alle Zeilen mit "Other" in Col2 entfernt wurden Ich kann jedoch nicht das Maximum von Col3 nach Col1 gruppieren.
Ich habe mich gefragt, ob es eine Möglichkeit gibt, eingebaute Pandas-Funktionen zu verwenden, um dies relativ einfach zu tun, anstatt eine völlig neue, maßgeschneiderte Funktion zu erstellen.
Antworten:
3 für die Antwort № 1Du kannst es versuchen
df[df.Col2 != "Other"].groupby("Col1").Col3.max()
Col1
A 5
B 13
So erstellen Sie eine neue Spalte:
df["new"]=df[df.Col2 != "Other"].groupby("Col1").Col3.transform("max")
df["new"] = df.new.ffill()
Col1 Col2 Col3 new
0 A Build 2 5.0
1 A Plan 5 5.0
2 A Other 17 5.0
3 B Test 5 13.0
4 B Build 13 13.0
5 B Other 12 13.0
6 B Buy 12 13.0
Erläuterung: Wählen Sie nur die Zeilen der df aus, bei denen der Col2-Wert nicht gleich "Other" ist.
Hier ist die Dokumentation von transform: Es gibt ein ähnlich indiziertes df mit transformierten Werten zurück, anstatt zu aggregieren.
1 für die Antwort № 2
Eine andere Möglichkeit, es mit zu verwechseln groupby
df.groupby([df.Col2.ne("Other"), "Col1"]).Col3.max()[True]
Col1
A 5
B 13
Name: Col3, dtype: int64
0 für die Antwort № 3
Die Antwort von @Vaishali ist ein guter Anfang, aber ichIch denke, es kann einige Probleme haben, vor allem wenn Sie ffill anwenden, um Na loszuwerden. Damit diese Methode funktioniert, müssen Sie Ihren Datenrahmen besonders sortieren. Um überzeugt zu sein, probieren Sie folgendes:
df = pd.DataFrame({"Col1":["A","A","A","B","B","B","B","C", "C"],
"Col2":["Build","Plan","Other","Test","Build","Other","Buy", "Buy","Other"],
"Col3":[2,5,17,5,13,12,12,14,5]})
df = df.sample(frac=1) #shuffle rows
df["new"]=df[df.Col2 != "Other"].groupby("Col1")["Col3"].transform("max")
df["new"] = df.new.ffill()
Und Sie können diese Ergebnisse erhalten, die nicht gut sind.
Col1 Col2 Col3 new
3 B Test 5 13.0
7 C Buy 14 14.0
6 B Buy 12 13.0
1 A Plan 5 5.0
0 A Build 2 5.0
5 B Other 12 5.0
8 C Other 5 5.0
4 B Build 13 13.0
2 A Other 17 13.0
Eine bessere Lösung: Definieren Sie zuerst diese Funktion.
def new_transform(df, exclude_cond,gbycol,target, agg_fun, ignore_value=None):
df["target_temp"] = df[target]
df.loc[eval(exclude_cond), "target_temp"] = ignore_value
tmp=df.groupby(gbycol)["target_temp"].transform(agg_fun)
df.drop("target_temp", axis=1, inplace=True)
return tmp
Es wird Ihr Datenrahmen, Ihre exculde_cond alsZeichenfolge, Ihre Gruppe als Liste von Zeichenfolgen oder eine Zeichenfolge, der Name der Zielspalte, für die die Berechnung ausgeführt wird, die Aggregationsfunktion und einen von der Aggregationsfunktion ignorierten Wert (Keine wird für die wichtigsten Agg-Funktionen verwendet)
Beispiel:
df = pd.DataFrame({"Col1":["A","A","A","B","B","B","B","C", "C"],
"Col2":["Build","Plan","Other","Test","Build","Other","Buy", "Buy","Other"],
"Col3":[2,5,17,5,13,12,12,14,5]})
df = df.sample(frac=1)
df["new"]=new_transform(df, "df["Col2"]=="Build"", ["Col1"],"Col3", "sum", np.nan)
Wir bekommen die richtigen Berechnungen:
Col1 Col2 Col3 new
3 B Test 5 29.0
2 A Other 17 22.0
4 B Build 13 29.0
6 B Buy 12 29.0
7 C Buy 14 19.0
1 A Plan 5 22.0
5 B Other 12 29.0
0 A Build 2 22.0
8 C Other 5 19.0