2017-12-29 25 views
2

Ich habe einen Pandas-Datenrahmen, den ich nach einem bestimmten Wort (Test) in einer Spalte filtern möchte. Ich habe versucht:Wie pandas Dataframe nach String zu filtern?

df[df[col].str.contains('test')]

Aber es gibt einen leeren Datenrahmen nur mit den Spaltennamen. Für die Ausgabe suche ich nach einem Datenrahmen, der alle Zeilen enthält, die das Wort "test" enthalten. Was kann ich tun?

EDIT (hinzuzufügen Proben):

data = pd.read_csv(/...csv)

Daten hat 5 cols, einschließlich 'BusinessDescription', und ich möchte alle Zeilen extrahieren, die das Wort 'dental' (Groß- und Kleinschreibung) in der Business Description col haben so verwendet, I:

filtered = data[data['BusinessDescription'].str.contains('dental')==True]

und ich bekomme einen leeren Datenrahmen, mit nur den Header-Namen der 5 Spalten.

+0

Können Sie einige Datenmuster hinzufügen? Weil es gut funktionieren sollte. – jezrael

+0

Ich habe gerade den ursprünglichen Beitrag bearbeitet, um mehr Details zu enthalten! – eh2699

+2

Für zukünftige Programmierung würde ich empfehlen, das Schlüsselwort 'df' anstelle von' data' zu verwenden, wenn Sie auf Datenrahmen verweisen. Es ist der übliche Weg, diese Notation zu verwenden. –

Antwort

4

Es scheint hinzufügen müssen Sie flags in contains Parameter:

import re 

filtered = data[data['BusinessDescription'].str.contains('dental', flags = re.IGNORECASE)] 

Eine andere Lösung, dank Anton vBR ist zuerst in Kleinbuchstaben konvertieren:

filtered = data[data['BusinessDescription'].str.lower().str.contains('dental')] 

Beispiel:
Für zukünftige Programmierung würde ich mit dem Stichwort df anstelle von Daten empfehlen, wenn du Datenrahmen beziehen. Es ist der übliche Weg, diese Notation zu verwenden.

import pandas as pd 

data = dict(BusinessDescription=['dental fluss','DENTAL','Dentist']) 
df = pd.DataFrame(data) 
df[df['BusinessDescription'].str.lower().str.contains('dental')] 

    BusinessDescription 
0  dental fluss 
1    DENTAL 

Timings:

d = dict(BusinessDescription=['dental fluss','DENTAL','Dentist']) 
data = pd.DataFrame(d) 
data = pd.concat([data]*10000).reset_index(drop=True) 

#print (data) 

In [122]: %timeit data[data['BusinessDescription'].str.contains('dental', flags = re.IGNORECASE)] 
10 loops, best of 3: 28.9 ms per loop 

In [123]: %timeit data[data['BusinessDescription'].str.lower().str.contains('dental')] 
10 loops, best of 3: 32.6 ms per loop 

Caveat:

Leistung hängt wirklich von der Daten - Größe von DataFrame und Anzahl von Werten entsprechen Zustand.

+1

Wenn der Fall das Problem ist, könnten wir '.lower()' nach 'str' richtig hinzufügen? Keine Notwendigkeit für ein Modul? –

+0

ja, ich hatte das '' 'import re'' vorher gemacht, aber das ignorecase Flag funktionierte perfekt, danke! – eh2699

+1

@AntonvBR - danke, – jezrael

1

Halten Sie die Zeichenfolge in Anführungszeichen eingeschlossen.

df[df['col'].str.contains('test')] 

Dank

+0

Sorry, habe vergessen, die Zitate in diesem Post hinzuzufügen. den Post jetzt bearbeitet! – eh2699

-1

Es ist auch OK funktioniert, wenn Sie eine Bedingung

df[df['col'].str.contains('test') == True] 
+0

ja ich habe das auch versucht, aber immer noch ein leeres datenfeld mit col-überschriften ... ich frage mich, ob es etwas mit dem datentyp zu tun hat? – eh2699

+0

Downvotes, weil die Bedingungen in Python gegen == True ausgewertet werden, wodurch diese bereits redundant ist. –

Verwandte Themen