Ich habe einen Pandas DataFrame und möchte Zeilen daraus löschen, bei denen die Länge der Zeichenfolge in einer bestimmten Spalte größer als 2 ist.
Ich erwarte, dies tun zu können (gemäß dieser Antwort ):
df[(len(df['column name']) < 2)]
aber ich bekomme nur den Fehler:
KeyError: u'no item named False'
Was mache ich falsch?
(Hinweis: Ich weiß, dass ich df.dropna()
damit Zeilen NaN
entfernen kann , die irgendwelche enthalten , aber ich habe nicht gesehen, wie Zeilen basierend auf einem bedingten Ausdruck entfernt werden können.)
df[[(len(x) < 2) for x in df['column name']]]
aber deines ist viel schöner. Danke für Ihre Hilfe!df[df['column name'].map(lambda x: str(x)!=".")]
pandas 0.23.4
und Python 3.6.copy()
am Ende ein hinzufügen , falls Sie diesen Datenrahmen später bearbeiten möchten (wenn Sie beispielsweise neue Spalten zuweisen, wird die Warnung "Ein Wert wird für eine Kopie eines Slice aus einem DataFrame festgelegt" ausgelöst.Um den Originaltitel dieser Frage "So löschen Sie Zeilen aus einem Pandas-DataFrame basierend auf einem bedingten Ausdruck" direkt zu beantworten (was meines Wissens nicht unbedingt das Problem des OP ist, aber anderen Benutzern helfen könnte, auf diese Frage zu stoßen), besteht eine Möglichkeit darin die Drop- Methode:
df = df.drop(some labels)
df = df.drop(df[<some boolean condition>].index)
Beispiel
So entfernen Sie alle Zeilen, in denen die Spalte 'score' <50 ist:
df = df.drop(df[df.score < 50].index)
In-Place-Version (wie in den Kommentaren angegeben)
df.drop(df[df.score < 50].index, inplace=True)
Mehrere Bedingungen
(siehe Boolesche Indizierung )
So entfernen Sie alle Zeilen, in denen die Spalte 'score' <50 und> 20 ist
df = df.drop(df[(df.score < 50) & (df.score > 20)].index)
quelle
reset_index()
). Ich habe das auf die harte Tour herausgefunden, als viele Zeilen aus meinem Datenrahmen entfernt wurden.test = df.drop(df[df['col1'].dtype == str].index)
aber ich bekomme den Fehler, denKeyError: False
ich auch versucht habedf.drop(df[df.col1.dtype == str].index)
unddf.drop(df[type(df.cleaned_norm_email) == str].index)
aber nichts scheint zu funktionieren? Kann mir jemand raten. Vielen Dank! @ Benutzerdf[(df.score < 50) & (df.score > 20)]
als Teil Ihrer Antwort berechnen . Wenn Sie dies rückgängig machendf = df[(df.score >= 50) | (df.score <= 20)]
würden, würden Sie Ihre Antwort viel schneller erhalten.Sie können das
DataFrame
einer gefilterten Version von sich selbst zuweisen :Das ist schneller als
drop
:quelle
Ich werde die generische Lösung von @ User erweitern, um eine
drop
kostenlose Alternative bereitzustellen . Dies ist für Leute, die hier basierend auf dem Titel der Frage gerichtet sind (nicht das Problem von OP).Angenommen, Sie möchten alle Zeilen mit negativen Werten löschen. Eine Linerlösung ist: -
Schritt für Schritt Erklärung: -
Lassen Sie uns einen 5x5 zufälligen Normalverteilungsdatenrahmen erzeugen
Lassen Sie die Bedingung Negative löschen. Ein boolescher df, der die Bedingung erfüllt: -
Eine boolesche Reihe für alle Zeilen, die die Bedingung erfüllen. Hinweis: Wenn ein Element in der Zeile die Bedingung nicht erfüllt, wird die Zeile als falsch markiert
Filtern Sie schließlich Zeilen aus dem Datenrahmen basierend auf der Bedingung heraus
Sie können es zurück zu df zuweisen , um tatsächlich löschen vs Filter über ing getan
df = df[(df > 0).all(axis=1)]
Dies kann leicht erweitert werden, um Zeilen herauszufiltern, die NaNs enthalten (nicht numerische Einträge): -
df = df[(~df.isnull()).all(axis=1)]
Dies kann auch für folgende Fälle vereinfacht werden: Löschen Sie alle Zeilen, in denen Spalte E negativ ist
Ich möchte mit einigen Profilstatistiken enden, warum die @ User-
drop
Lösung langsamer ist als die rohe spaltenbasierte Filterung: -Eine Säule ist im Grunde ein
Series
dh einNumPy
Array, kann es ohne Kosten indexiert werden. Für Leute, die daran interessiert sind, wie sich die zugrunde liegende Speicherorganisation auf die Ausführungsgeschwindigkeit auswirkt, gibt es hier einen großartigen Link zur Beschleunigung von Pandas :quelle
In Pandas können Sie
str.len
mit Ihrer Grenze arbeiten und das Boolesche Ergebnis verwenden, um sie zu filtern.quelle
Wenn Sie Zeilen eines Datenrahmens auf der Grundlage einer komplizierten Bedingung für den Spaltenwert löschen möchten, kann das Schreiben auf die oben gezeigte Weise kompliziert sein. Ich habe die folgende einfachere Lösung, die immer funktioniert. Nehmen wir an, Sie möchten die Spalte mit 'Kopfzeile' löschen, also nehmen Sie diese Spalte zuerst in eine Liste auf.
Wenden Sie nun eine Funktion auf jedes Element der Liste an und fügen Sie diese in eine Panda-Serie ein:
In meinem Fall habe ich nur versucht, die Anzahl der Token zu ermitteln:
Fügen Sie nun eine zusätzliche Spalte mit der obigen Reihe in den Datenrahmen ein:
Jetzt können wir Bedingungen auf die neue Spalte anwenden, wie zum Beispiel:
quelle