Ich mag , dass meine benutzerdefinierte Funktion anzuwenden (es verwendet einen if-else - Leiter) zu diesen sechs Säulen ( ERI_Hispanic
, ERI_AmerInd_AKNatv
, ERI_Asian
, ERI_Black_Afr.Amer
, ERI_HI_PacIsl
, ERI_White
) in jeder Reihe meines Datenrahmen.
Ich habe andere Methoden als andere Fragen ausprobiert, kann aber immer noch nicht die richtige Antwort für mein Problem finden. Das Entscheidende dabei ist, dass die Person, wenn sie als Hispanic gezählt wird, nicht als etwas anderes gezählt werden kann. Selbst wenn sie eine "1" in einer anderen ethnischen Spalte haben, werden sie immer noch als Hispanic gezählt, nicht als zwei oder mehr Rassen. Wenn die Summe aller ERI-Spalten größer als 1 ist, werden sie als zwei oder mehr Rassen gezählt und können nicht als eindeutige ethnische Zugehörigkeit gezählt werden (außer Hispanic). Hoffentlich macht das Sinn. Jede Hilfe wird sehr geschätzt.
Es ist fast so, als würde man eine for-Schleife durch jede Zeile führen. Wenn jeder Datensatz ein Kriterium erfüllt, werden sie zu einer Liste hinzugefügt und aus dem Original entfernt.
Aus dem folgenden Datenrahmen muss ich eine neue Spalte basierend auf der folgenden Spezifikation in SQL berechnen:
========================= KRITERIEN ======================== =======
IF [ERI_Hispanic] = 1 THEN RETURN “Hispanic”
ELSE IF SUM([ERI_AmerInd_AKNatv] + [ERI_Asian] + [ERI_Black_Afr.Amer] + [ERI_HI_PacIsl] + [ERI_White]) > 1 THEN RETURN “Two or More”
ELSE IF [ERI_AmerInd_AKNatv] = 1 THEN RETURN “A/I AK Native”
ELSE IF [ERI_Asian] = 1 THEN RETURN “Asian”
ELSE IF [ERI_Black_Afr.Amer] = 1 THEN RETURN “Black/AA”
ELSE IF [ERI_HI_PacIsl] = 1 THEN RETURN “Haw/Pac Isl.”
ELSE IF [ERI_White] = 1 THEN RETURN “White”
Kommentar: Wenn das ERI-Flag für Hispanic True ist (1), wird der Mitarbeiter als „Hispanic“ klassifiziert.
Kommentar: Wenn mehr als 1 nicht-hispanisches ERI-Flag wahr ist, geben Sie "Zwei oder mehr" zurück.
===================== DATAFRAME ============================
lname fname rno_cd eri_afr_amer eri_asian eri_hawaiian eri_hispanic eri_nat_amer eri_white rno_defined
0 MOST JEFF E 0 0 0 0 0 1 White
1 CRUISE TOM E 0 0 0 1 0 0 White
2 DEPP JOHNNY 0 0 0 0 0 1 Unknown
3 DICAP LEO 0 0 0 0 0 1 Unknown
4 BRANDO MARLON E 0 0 0 0 0 0 White
5 HANKS TOM 0 0 0 0 0 1 Unknown
6 DENIRO ROBERT E 0 1 0 0 0 1 White
7 PACINO AL E 0 0 0 0 0 1 White
8 WILLIAMS ROBIN E 0 0 1 0 0 0 White
9 EASTWOOD CLINT E 0 0 0 0 0 1 White
Antworten:
OK, zwei Schritte dazu - der erste besteht darin, eine Funktion zu schreiben, die die gewünschte Übersetzung ausführt - Ich habe ein Beispiel zusammengestellt, das auf Ihrem Pseudocode basiert:
Möglicherweise möchten Sie dies durchgehen, aber es scheint den Trick zu tun - beachten Sie, dass der Parameter, der in die Funktion eingeht, als Serienobjekt mit der Bezeichnung "Zeile" betrachtet wird.
Verwenden Sie als Nächstes die Apply-Funktion in Pandas, um die Funktion anzuwenden - z
Beachten Sie den Bezeichner axis = 1, dh, die Anwendung erfolgt auf Zeilen- und nicht auf Spaltenebene. Die Ergebnisse sind hier:
Wenn Sie mit diesen Ergebnissen zufrieden sind, führen Sie sie erneut aus und speichern Sie die Ergebnisse in einer neuen Spalte in Ihrem ursprünglichen Datenrahmen.
Der resultierende Datenrahmen sieht folgendermaßen aus (scrollen Sie nach rechts, um die neue Spalte anzuzeigen):
quelle
df.apply(label_race, axis=1)
return 'Other'
Zeile ändern , inreturn row['rno_defined']
die dies erfolgen soll Ersetzen Sie den Wert aus dieser Spalte in den Fällen, in denen die Menge der if / then-Anweisungen keine Übereinstimmung findet (dh wo derzeit "Andere" angezeigt wird).df.apply(lambda row: label_race (row),axis=1)
zudf.apply(label_race, axis=1)
Da dies das erste Google-Ergebnis für "Pandas neue Spalte von anderen" ist, ist hier ein einfaches Beispiel:
Wenn Sie das bekommen
SettingWithCopyWarning
, können Sie es auch so machen:Quelle: https://stackoverflow.com/a/12555510/243392
Und wenn Ihr Spaltenname Leerzeichen enthält, können Sie die folgende Syntax verwenden:
Und hier ist die Dokumentation zum Anwenden und Zuweisen .
quelle
SettingWithCopyWarning
wenn ich es tue.df['c'] = df.apply(lambda row: row.a + row.b, axis=1)
Ist das hier ein echtes Problem, oder sollte ich mir darüber keine Sorgen machen?Die obigen Antworten sind vollkommen gültig, aber es gibt eine vektorisierte Lösung in Form von
numpy.select
. Auf diese Weise können Sie Bedingungen definieren und dann Ausgaben für diese Bedingungen definieren, viel effizienter als mitapply
:Definieren Sie zunächst die Bedingungen:
Definieren Sie nun die entsprechenden Ausgänge:
Schließlich mit
numpy.select
:Warum sollte
numpy.select
über verwendet werdenapply
? Hier einige Leistungsprüfungen:Durch
numpy.select
die Verwendung können wir die Leistung erheblich verbessern, und die Diskrepanz nimmt nur zu, wenn die Daten wachsen.quelle
.apply()
nimmt eine Funktion als ersten Parameter auf; Übergeben Sie dielabel_race
Funktion wie folgt:Sie müssen keine Lambda-Funktion erstellen, um eine Funktion zu übergeben.
quelle
Versuche dies,
O / P:
verwenden
.loc
stattapply
.es verbessert die Vektorisierung.
.loc
funktioniert auf einfache Weise, maskiert Zeilen basierend auf der Bedingung, wendet Werte auf die Einfrierzeilen an.Weitere Informationen finden Sie unter .loc docs
Leistungsmetriken:
Akzeptierte Antwort:
Meine vorgeschlagene Antwort:
quelle