Ich habe eine DataFrame
mit 4 Spalten, von denen 2 Zeichenfolgenwerte enthalten. Ich habe mich gefragt, ob es eine Möglichkeit gibt, Zeilen basierend auf einer teilweisen Zeichenfolgenübereinstimmung mit einer bestimmten Spalte auszuwählen.
Mit anderen Worten, eine Funktion oder Lambda-Funktion, die so etwas tun würde
re.search(pattern, cell_in_question)
Rückgabe eines Booleschen Werts. Ich bin mit der Syntax von vertraut df[df['A'] == "hello world"]
, kann aber anscheinend keinen Weg finden, dasselbe mit einem partiellen String-Match zu tun 'hello'
.
Würde mich jemand in die richtige Richtung weisen können?
df[df['A'].str.contains("Hello|Britain")]
.str.contains
zur Verwendung von.query()
API zu konvertieren ?df[df['value'].astype(str).str.contains('1234.+')]
zum Herausfiltern von Spalten ohne Zeichenfolge.Ich habe die oben vorgeschlagene Lösung ausprobiert:
und habe einen Fehler bekommen:
Sie können NA-Werte
False
wie folgt umwandeln :quelle
df[df['A'].astype(str).str.contains("Hello|Britain")]
funktionierte auchDieser Beitrag ist für Leser gedacht, die wollen
isin
)... und möchten mehr darüber erfahren, welche Methoden anderen vorgezogen werden sollten.
(PS: Ich habe viele Fragen zu ähnlichen Themen gesehen. Ich dachte, es wäre gut, dies hier zu belassen.)
Grundlegende Teilstringsuche
str.contains
kann verwendet werden, um entweder Teilstringsuchen oder Regex-basierte Suche durchzuführen. Die Suche basiert standardmäßig auf regulären Ausdrücken, sofern Sie sie nicht explizit deaktivieren.Hier ist ein Beispiel für eine Regex-basierte Suche:
Manchmal ist keine Regex-Suche erforderlich.
regex=False
Geben Sie dies an , um sie zu deaktivieren.In Bezug auf die Leistung ist die Regex-Suche langsamer als die Suche nach Teilzeichenfolgen:
Vermeiden Sie die Verwendung von Regex-basierter Suche, wenn Sie diese nicht benötigen.
Adressierung
ValueError
sManchmal führt das Durchführen einer Teilstringsuche und das Filtern des Ergebnisses zu
Dies liegt normalerweise an gemischten Daten oder NaNs in Ihrer Objektspalte.
Auf alles, was kein String ist, können keine String-Methoden angewendet werden. Das Ergebnis ist also (natürlich) NaN. Geben Sie in diesem Fall an,
na=False
dass Nicht-String-Daten ignoriert werden sollen.Suche nach mehreren Teilzeichenfolgen
Dies wird am einfachsten durch eine Regex-Suche mit der Regex-ODER-Pipe erreicht.
Sie können auch eine Liste mit Begriffen erstellen und diese dann verbinden:
Manchmal ist es ratsam, sich Ihren Begriffen zu entziehen, wenn sie Zeichen enthalten, die als Regex-Metazeichen interpretiert werden können . Wenn Ihre Begriffe eines der folgenden Zeichen enthalten ...
Dann müssen Sie verwenden
re.escape
, um ihnen zu entkommen :re.escape
hat den Effekt, dass die Sonderzeichen entkommen, sodass sie buchstäblich behandelt werden.Übereinstimmende ganze Wörter
Standardmäßig sucht die Teilstringsuche nach dem angegebenen Teilstring / Muster, unabhängig davon, ob es sich um ein vollständiges Wort handelt oder nicht. Um nur vollständige Wörter zu finden, müssen wir hier reguläre Ausdrücke verwenden - insbesondere muss unser Muster Wortgrenzen angeben (
\b
).Zum Beispiel,
Nun überlegen Sie,
v / s
Suche nach mehreren ganzen Wörtern
Ähnlich wie oben, außer dass wir
\b
dem verbundenen Muster eine Wortgrenze ( ) hinzufügen .Wo
p
sieht das so aus?Eine großartige Alternative: Verwenden Sie Listenverständnisse !
Weil du es kannst! Und du solltest! Sie sind normalerweise etwas schneller als String-Methoden, da String-Methoden schwer zu vektorisieren sind und normalerweise schleifenförmige Implementierungen aufweisen.
Anstatt,
Verwenden Sie den
in
Operator in einer Liste comp,Anstatt,
Verwenden Sie
re.compile
(um Ihren regulären Ausdruck zwischenzuspeichern) +Pattern.search
in einer Listenkomposition.Wenn "col" NaNs hat, dann anstelle von
Verwenden,
Weitere Optionen für Teil String Matching:
np.char.find
,np.vectorize
,DataFrame.query
.Zusätzlich zu
str.contains
und Listenverständnissen können Sie auch die folgenden Alternativen verwenden.np.char.find
Unterstützt nur die Suche nach Teilzeichenfolgen (gelesen: kein regulärer Ausdruck).
np.vectorize
Dies ist ein Wrapper um eine Schleife, aber mit geringerem Overhead als die meisten Pandas-
str
Methoden.Regex-Lösungen möglich:
DataFrame.query
Unterstützt String-Methoden über die Python-Engine. Dies bietet keine sichtbaren Leistungsvorteile, ist jedoch hilfreich, um zu wissen, ob Sie Ihre Abfragen dynamisch generieren müssen.
Weitere Informationen zu
query
undeval
Methodenfamilien finden Sie unter Dynamic Expression Evaluation in Pandas mit pd.eval () .Empfohlene Verwendung Vorrang
str.contains
für seine Einfachheit und Leichtigkeit beim Umgang mit NaNs und gemischten Datennp.vectorize
df.query
quelle
any(needle in haystack for needling in ['foo', 'bar'] and haystack in (df['col'], df['col2']))
und Variationen habe ich alle Drossel versucht (es beschwert sichany()
und zu Recht so ... Aber der Doc ist selig unklar, wie man eine solche Abfrage macht.df[['col1', 'col2']].apply(lambda x: x.str.contains('foo|bar')).any(axis=1)
Wenn sich jemand fragt, wie ein verwandtes Problem ausgeführt werden soll: "Spalte nach Teilzeichenfolge auswählen"
Verwenden:
Um Zeilen durch partielle Zeichenfolgenübereinstimmung auszuwählen, übergeben Sie sie
axis=0
an den Filter:quelle
df.loc[:, df.columns.str.contains('a')]
df.filter(like='a')
Kurzer Hinweis: Wenn Sie eine Auswahl anhand einer im Index enthaltenen Teilzeichenfolge vornehmen möchten, versuchen Sie Folgendes:
quelle
Angenommen, Sie haben Folgendes
DataFrame
:Sie können den
in
Operator immer in einem Lambda-Ausdruck verwenden, um Ihren Filter zu erstellen.Der Trick dabei ist, die
axis=1
Option inapply
zu verwenden, um Elemente zeilenweise an die Lambda-Funktion zu übergeben, im Gegensatz zu spaltenweise.quelle
Folgendes habe ich letztendlich für Teilstring-Übereinstimmungen getan. Wenn jemand eine effizientere Möglichkeit hat, lassen Sie es mich bitte wissen.
quelle
Die Verwendung von enthält hat für meine Zeichenfolge mit Sonderzeichen nicht gut funktioniert. Find hat aber funktioniert.
quelle
Davor gibt es Antworten, die die angeforderte Funktion erfüllen, trotzdem möchte ich den allgemeinsten Weg zeigen:
Auf diese Weise erhalten Sie die Spalte, nach der Sie suchen, unabhängig davon, wie sie geschrieben wurde.
(Offensichtlich müssen Sie für jeden Fall den richtigen Regex-Ausdruck schreiben.)
quelle
Vielleicht möchten Sie in allen Spalten des Pandas-Datenrahmens nach Text suchen, und nicht nur in deren Teilmenge. In diesem Fall hilft der folgende Code.
Warnung. Diese Methode ist relativ langsam, wenn auch zweckmäßig.
quelle
Sollten Sie eine Suche ohne Berücksichtigung der Groß- und Kleinschreibung nach einer Zeichenfolge in einer Pandas-Datenrahmenspalte durchführen müssen:
quelle