Jak sprawdzić, czy łańcuch zawiera jeden z podciągów na liście, w Pandzie?

Czy istnieje jakaś funkcja, która byłaby odpowiednikiem kombinacji df.isin() i df[col].str.contains()?

Na przykład, powiedzmy, że mam serię s = pd.Series(['cat','hat','dog','fog','pet']), i chcę znaleźć wszystkie miejsca, w których s zawiera cokolwiek z ['og', 'at'], chciałbym dostać wszystko, oprócz "zwierzaka".

Mam rozwiązanie, ale jest raczej nieeleganckie:

searchfor = ['og', 'at']
found = [s.str.contains(x) for x in searchfor]
result = pd.DataFrame[found]
result.any()
Czy jest na to lepszy sposób?
Author: smci, 2014-10-26

3 answers

Jedną z opcji jest użycie znaku regex |, aby spróbować dopasować każdy podłańcuch w słowach Z Serii s (nadal używając str.contains).

Możesz skonstruować regex łącząc słowa w searchfor z |:

>>> searchfor = ['og', 'at']
>>> s[s.str.contains('|'.join(searchfor))]
0    cat
1    hat
2    dog
3    fog
dtype: object

Jak @AndyHayden zauważył w komentarzach poniżej, uważaj, czy podciągi mają znaki specjalne, takie jak $ i ^, które chcesz dopasować dosłownie. Znaki te mają określone znaczenia w kontekście wyrażeń regularnych i wpłynie na dopasowanie.

Możesz uczynić listę podłańcuchów bezpieczniejszymi, unikając znaków niealfanumerycznych za pomocą re.escape:

>>> import re
>>> matches = ['$money', 'x^y']
>>> safe_matches = [re.escape(m) for m in matches]
>>> safe_matches
['\\$money', 'x\\^y']

Ciągi znaków z tej nowej Listy będą pasowały do każdego znaku dosłownie, gdy zostaną użyte z str.contains.

 251
Author: Alex Riley,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-02-28 20:42:50

Możesz użyć str.contains samodzielnie ze wzorem regex używając OR (|):

s[s.str.contains('og|at')]

Lub możesz dodać serię do dataframe następnie użyć str.contains:

df = pd.DataFrame(s)
df[s.str.contains('og|at')] 

Wyjście:

0 cat
1 hat
2 dog
3 fog 
 57
Author: l'L'l,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-10-26 21:33:30

Oto jednolinijkowa lambda, która również działa:

df["TrueFalse"] = df['col1'].apply(lambda x: 1 if any(i in x for i in searchfor) else 0)

Wejście:

searchfor = ['og', 'at']

df = pd.DataFrame([('cat', 1000.0), ('hat', 2000000.0), ('dog', 1000.0), ('fog', 330000.0),('pet', 330000.0)], columns=['col1', 'col2'])

   col1  col2
0   cat 1000.0
1   hat 2000000.0
2   dog 1000.0
3   fog 330000.0
4   pet 330000.0

Zastosuj Lambda:

df["TrueFalse"] = df['col1'].apply(lambda x: 1 if any(i in x for i in searchfor) else 0)

Wyjście:

    col1    col2        TrueFalse
0   cat     1000.0      1
1   hat     2000000.0   1
2   dog     1000.0      1
3   fog     330000.0    1
4   pet     330000.0    0
 3
Author: Grant Shannon,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-04-01 21:30:05