2016-09-07 12 views
5

df (Panda DataFame) ma trzy wiersze.python pandas.Series.str.contains CAŁE WORD

col_name 
"This is Donald." 
"His hands are so small" 
"Why are his fingers so short?" 

Chciałbym wyodrębnić wiersz zawierający "jest" i "mały".

Jeśli robię

df.col_name.str.contains("is|small", case=False) 

Potem łapie „jego” jak dobrze którego nie chcę.

Czy poniżej zapytania jest właściwy sposób na złapanie całego słowa w df.series?

df.col_name.str.contains("\bis\b|\bsmall\b", case=False) 

Odpowiedz

5

Nie, regex /bis/b|/bsmall/b zawiedzie bo używasz /b, nie \b które oznacza „granicę słowa”.

Zmień to i otrzymasz mecz. Zalecam użycie tego atrybutu:

\b(is|small)\b 

To wyrażenie jest trochę szybsze i bardziej czytelne, przynajmniej dla mnie.

+0

Dziękuję. Odbiłem twój punkt/b -> \ b. Nadal chcesz poczekać kilka kolejnych dni, aby sprawdzić, czy jest jakiś inny sposób na złapanie całego słowa. – Aaron

+0

stycznie, musiałem dodać 'r' przed ciągiem, aby uruchomić go: każdy wie, dlaczego? Nie znalazłem żadnego odniesienia do niego .. – mccc

+0

Cóż, najwyraźniej '' char powoduje, że jest ono domyślnie w wyrażeniu regularnym, natomiast '\ b' nie .. – mccc

0

Twoja droga (z/b) nie działa dla mnie. Nie wiem, dlaczego nie możesz użyć operatora logicznego i (&), ponieważ uważam, że właśnie tego chcesz.

To głupi sposób to zrobić, ale to działa:

mask = lambda x: ("is" in x) & ("small" in x) 
series_name.apply(mask) 
+1

chodzi o to, aby złapać całe słowo: Czy (O) jego (x) – Aaron

+0

Podany przez ciebie przykład jest mylący w tym względzie, chociaż widzę, że zmieniłeś go, aby był nieco jaśniejszy. To rozwiązuje to, co pierwotnie powiedziałeś, że problem był "Chciałbym wyodrębnić wiersz, który zawiera" jest "i" mały "." – szeitlin

0

Po pierwsze, możesz przekonwertować wszystko na małe litery, usunąć znaki interpunkcyjne i białe znaki, a następnie przekonwertować wynik na zestaw słów.

import string 

df['words'] = [set(words) for words in 
    df['col_name'] 
    .str.lower() 
    .str.replace('[{0}]*'.format(string.punctuation), '') 
    .str.strip() 
    .str.split() 
] 

>>> df 
         col_name        words 
0    This is Donald.     {this, is, donald} 
1   His hands are so small   {small, his, so, are, hands} 
2 Why are his fingers so short? {short, fingers, his, so, are, why} 

Można teraz używać logiczną indeksowanie aby sprawdzić, czy wszystkie słowa są swój cel w tych nowych zestawów słownych.

target_words = ['is', 'small'] 
# Convert target words to lower case just to be safe. 
target_words = [word.lower() for word in target_words] 

df['match'] = df.words.apply(lambda words: all(target_word in words 
               for target_word in target_words)) 


print(df) 
# Output: 
#       col_name        words match 
# 0    This is Donald.     {this, is, donald} False 
# 1   His hands are so small   {small, his, so, are, hands} False 
# 2 Why are his fingers so short? {short, fingers, his, so, are, why} False  

target_words = ['so', 'small'] 
target_words = [word.lower() for word in target_words] 

df['match'] = df.words.apply(lambda words: all(target_word in words 
               for target_word in target_words)) 

print(df) 
# Output: 
# Output: 
#       col_name        words match 
# 0    This is Donald.     {this, is, donald} False 
# 1   His hands are so small   {small, his, so, are, hands} True 
# 2 Why are his fingers so short? {short, fingers, his, so, are, why} False  

aby wyodrębnić wiersze pasujące:

>>> df.loc[df.match, 'col_name'] 
# Output: 
# 1 His hands are so small 
# Name: col_name, dtype: object 

, aby to wszystko w jednym rachunku przy użyciu logiczną indeksowania:

df.loc[[all(target_word in word_set for target_word in target_words) 
     for word_set in (set(words) for words in 
         df['col_name'] 
         .str.lower() 
         .str.replace('[{0}]*'.format(string.punctuation), '') 
         .str.strip() 
         .str.split())], :] 
+0

Dzięki za odpowiedź .. Próbuję użyć wbudowanego indeksowania Pandas (ponieważ moja tabela zawiera około 500 tysięcy wierszy), ale myślę, że indeksujesz ją samemu ...? – Aaron

+2

Nie jesteś pewien co masz na myśli. To wykorzystuje indeksowanie Pandas. – Alexander

+0

Spowoduje to zwrócenie dopasowania, ale nie dopasowanie całego ciągu! –

Powiązane problemy