2016-04-15 13 views
2

Ich habe eine Liste von Strings, die ich mit eine Suche durchzuführen müssen auf eine bestimmte Spalte in einem Datenrahmen:Spiel Unbekannt Anzahl der String-Elemente in Pandas Spalte

search_strings = ['foo bar', 'bar such foo', 'very wow foo'] 

Ich versuche Zeilen in der abrufen Datenrahmen, der den Wörtern in jeder Reihenfolge in jeder Zeichenfolge in der Liste entspricht. Der Datenrahmen könnte so aussehen:

ID string_col 
1 foo bar 
2 bar foo 
3 foo very bar 
4 bar such foo 
5 foo wow very 

Ich war froh zu finden, dass ich ein '|' Betreiber mit str.contains (ruft alle 5 Zeilen):

df[df['string_col'].str.contains('foo|bar')] 

Ich dachte, ich meine Liste, Split konnte Schleife durch und verbinden sie mit einem ‚&‘ zu tun etwas ähnliches (ich glaubte fälschlicherweise diese 4 Zeilen abrufen würde):

df[df['string_col'].str.contains('foo&bar')] 

Allerdings stellt sich heraus, dass dies nicht etwas ist, was Sie tun können. Irgendeine Idee, wie ich übereinstimmende Spalten basierend auf einer Liste von Zeichenfolgen mit jeweils einer unbekannten Anzahl von Wörtern leicht abrufen kann?

Danke!

Antwort

1

Sie können eine Liste Verständnis auf dem geteilten Zeichenfolge verwenden, um sicherzustellen, dass alle Zielwörter vorhanden sind:

words = ['foo', 'bar'] 
df['word_match'] = [all(word in values for word in words) 
        for values in df.string_col.str.split(" ")] 

>>> df 
    ID string_col word_match 
0 1  foo bar  True 
1 2  bar foo  True 
2 3 foo very bar  True 
3 4 bar such foo  True 
4 5  foo wow  False 

Timings

%timeit df['word_match'] = [all(word in values for word in words) for values in df.string_col.str.split(" ")] 
1000 loops, best of 3: 320 µs per loop 

%timeit df['word_match'] = df[df['string_col'].str.contains('foo') & df['string_col'].str.contains('bar')] 
1000 loops, best of 3: 1.23 ms per loop 

Bei größeren Datenmengen, übertrifft die zweite Methode leicht:

df2 = pd.concat([df]*10000, ignore_index=True) 

%timeit df2['word_match'] = [all(word in values for word in words) for values in df2.string_col.str.split(" ")] 
10 loops, best of 3: 70.9 ms per loop 

%timeit df2['word_match'] = df2[df2['string_col'].str.contains('foo') & df2['string_col'].str.contains('bar')] 
10 loops, best of 3: 63.7 ms per loop 
+0

wollen Sie mögen, um zu sehen, ob es ein Performance-Gewinn mit Ihren Daten ist mit 'all (Wort in Satz (Werte) für ...' – Alexander

1

Sie haben 2 Bedingungen passieren str.contains mit und wickeln diese in Klammern und verwenden &:

In [11]: 
df[df['string_col'].str.contains('foo') & df['string_col'].str.contains('bar')] 

Out[11]: 
    ID string_col 
0 1  foo bar 
1 2  bar foo 
2 3 foo very bar 
3 4 bar such foo 
+0

Dank! Ich habe meinen Beitrag mit etwas mehr Genauigkeit bearbeitet - ich habe eine Situation, in der ich nicht weiß, wie viele Wörter ich zuordnen muss. – eljusticiero67

+0

Sie haben soeben mehrere Masken definiert und '&' sie alle – EdChum

+0

Liebe zu hören, wie das funktioniert. Kannst du es ausarbeiten? – eljusticiero67

Verwandte Themen