Existe-t-il une fonction qui serait l’équivalent d’une combinaison de df.isin()
et df[col].str.contains()
?
Par exemple, disons que j’ai la série s = pd.Series(['cat','hat','dog','fog','pet'])
et que je veux trouver tous les endroits où s
contient l’un quelconque des ['og', 'at']
, Je voudrais tout avoir sauf 'animal'.
J'ai une solution, mais c'est plutôt inélégant:
searchfor = ['og', 'at']
found = [s.str.contains(x) for x in searchfor]
result = pd.DataFrame[found]
result.any()
Y a-t-il une meilleure manière de faire cela?
Une option consiste simplement à utiliser la regex |
caractère pour essayer de faire correspondre chacune des sous-chaînes des mots de votre série s
(toujours en utilisant str.contains
).
Vous pouvez construire l’expression rationnelle en joignant les mots dans searchfor
avec |
:
>>> searchfor = ['og', 'at']
>>> s[s.str.contains('|'.join(searchfor))]
0 cat
1 hat
2 dog
3 fog
dtype: object
Comme @AndyHayden l'a noté dans les commentaires ci-dessous, faites attention si vos sous-chaînes ont des caractères spéciaux tels que $
et ^
que vous voulez assortir littéralement. Ces caractères ont des significations spécifiques dans le contexte des expressions régulières et affecteront la correspondance.
Vous pouvez sécuriser votre liste de sous-chaînes en échappant des caractères non alphanumériques avec re.escape
:
>>> import re
>>> matches = ['$money', 'x^y']
>>> safe_matches = [re.escape(m) for m in matches]
>>> safe_matches
['\\$money', 'x\\^y']
Les chaînes figurant dans cette nouvelle liste correspondront littéralement à chaque caractère lorsqu’elles sont utilisées avec str.contains
.
Vous pouvez utiliser str.contains
Seul avec un motif regex utilisant OR (|)
:
s[s.str.contains('og|at')]
Ou vous pouvez ajouter la série à un dataframe
puis utiliser str.contains
:
df = pd.DataFrame(s)
df[s.str.contains('og|at')]
Sortie:
0 cat
1 hat
2 dog
3 fog