6 votes

Vérifiez si la chaîne de caractères est dans une autre colonne pandas

Voici mon DF

df= pd.DataFrame({'col1': ['[7]', '[30]', '[0]', '[7]'], 'col2': ['[0%, 7%]', '[30%]', '[30%, 7%]', '[7%']})

col1    col2    
[7]     [0%, 7%]
[30]    [30%]
[0]     [30%, 7%]
[7]     [7%]

Le but est de vérifie si la valeur de col1 est contenue dans col2 voici ce que j'ai essayé

df['test'] = df.apply(lambda x: str(x.col1) in str(x.col2), axis=1)

Voici la sortie attendue

col1    col2       col3
[7]     [0%, 7%]   True
[30]    [30%]      True
[0]     [30%, 7%]  False
[7]     [7%]       True

2voto

jezrael Points 290608

Utilisez Series.str.extractall pour obtenir les nombres, remodeler avec Series.unstack, puis comparer éventuellement avec DataFrame.isin et DataFrame.any:

df['test'] = (df['col2'].str.extractall('(\d+)')[0].unstack()
                        .isin(df['col1'].str.strip('[]'))
                        .any(axis=1))
print (df)
   col1       col2   test
0   [7]   [0%, 7%]   True
1  [30]      [30%]   True
2   [0]  [30%, 7%]  False
3   [7]       [7%]   True

2voto

mozway Points 233

Vous pouvez extraire les nombres des deux colonnes et joindre, puis vérifier s'il y a au moins une correspondance par id en utilisant eval+groupby+any:

(df['col2'].str.extractall('(?P\d+)').droplevel(1)
   .join(df['col1'].str[1:-1])
   .eval('col2 == col1')
   .groupby(level=0).any()
)

output:

0     True
1     True
2    False
3     True

2voto

Dani Mesejo Points 29634

Une approche:

import ast

# convertir en liste d'entiers
col2_lst = df["col2"].str.replace("%", "").apply(ast.literal_eval)

# vérifier l'inclusion dans la liste
df["col3"] = [all(bi in a for bi in b)  for a, b in zip(col2_lst, df["col1"].apply( ast.literal_eval)) ]

print(df)

Sortie

   col1       col2   col3
0   [7]   [0%, 7%]   True
1  [30]      [30%]   True
2   [0]  [30%, 7%]  False
3   [7]       [7%]   True

2voto

Wiktor Stribiżew Points 100073

Vous pouvez également remplacer les crochets avec des limites de mot \b et utiliser re.search comme suit

import re
#...
df.apply(lambda x: bool(re.search(x['col1'].replace("[",r"\b").replace("]",r"\b"), x['col2'])), axis=1)
# => 0     True
#    1     True
#    2    False
#    3     True
#    dtype: bool

Cela fonctionnera car \b7\b trouvera une correspondance dans [0%, 7%] car 7 n'est ni précédé ni suivi de lettres, de chiffres ou de soulignés. Aucune correspondance ne sera trouvée dans [30%, 7%] car \b0\b ne correspond pas à un zéro après un chiffre (ici, 3).

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X