J'ai le dataframe suivant dans les pandas
m = re.search('TANK (\d+)', 'TANK 5', re.IGNORECASE)
m.group(1)
Je veux extraire des nombres de la colonne text qui suit le modèle suivant
numéro après MS, HS et XP, numéro après TANK et numéro après Tank_
Dataframe souhaité
ID text new_text 1 T7MS1 1 2 T5HS2 2 3 T3XP1 1 4 Tank_3 3 5 TANK 5 5 6 System System
Je peux le faire en suivant pour 1 modèle
ID text 1 T7MS1 2 T5HS2 3 T3XP1 4 Tank_3 5 TANK 5 6 System
Mais comment combiner tous les motifs en un et l'appliquer à la colonne.
5 Réponses :
Une fonction simple avec l'instruction if peut résoudre votre problème:
0 1 1 3 2 5 3 System dtype: object
Ou vous pouvez utiliser ce modèle r "\ d + $" code > si vous ne voulez pas faire correspondre le numéro après un mot spécifique.
$ dans le modèle signifie la fin de la chaîne .
Il renvoie:
s = pd.Series(["T7MS1","Tank_3","TANK 5", "System"])
pattern= "[MS|HS|XP|TANK |Tank_](\d+)"
def fetch_num(txt):
result = re.findall(pattern,txt)
if result: # if matched
return result[0]
else:
return txt
s.apply(fetch_num)
p >
Votre expression régulière ne signifie pas ce que vous pensez que cela signifie. Il correspond uniquement au dernier caractère précédant le nombre.
Si le nombre est toujours le dernier caractère du terme, vous pouvez simplement utiliser les méthodes de chaîne de la série Pandas, comme ceci:
df['new_text'] = df.text.str.slice(-1)
Sinon, car il y a des nombres au milieu que vous ne ne veux pas, une solution RegEx pourrait être possible, étant donné plus d'informations sur vos paramètres.
Si les nombres sont toujours la dernière lettre, il vous suffit d'utiliser Series.str [-1] :
df['new_text'] = df['new_text'].fillna(df['text'])
id text new_text
0 1 T7MS1 1
1 2 T5HS2 2
2 3 T3XP1 1
3 4 Tank_3 3
4 5 TANK 5 5
5 6 System System
Ou si vous voulez un numéro après MS, HS et XP, TANK et Tank_ uniquement: p>
df['new_text'] = df.text.str.extract(r'(?:MS|HS|XP|TANK |Tank_)(\d+)') df id text new_text 0 1 T7MS1 1 1 2 T5HS2 2 2 3 T3XP1 1 3 4 Tank_3 3 4 5 TANK 5 5
Vous pouvez remplir les valeurs nulles en utilisant:
df= pd.DataFrame({'id': [1, 2, 3, 4, 5],
'text': ['T7MS1', 'T5HS2', 'T3XP1', 'Tank_3', 'TANK 5']})
df
id text
0 1 T7MS1
1 2 T5HS2
2 3 T3XP1
3 4 Tank_3
4 5 TANK 5
df['new_text'] = df.text.str[-1]
df
id text new_text
0 1 T7MS1 1
1 2 T5HS2 2
2 3 T3XP1 1
3 4 Tank_3 3
4 5 TANK 5 5
Encore une chose, j'ai mis à jour la question, par exemple tout modèle en dehors de ce qui est mentionné dans la question doit rester le même dans la colonne new_text .
@Neil J'ai mis à jour ma réponse. Veuillez vérifier si cela vous aide.
Je souhaite extraire des nombres de la colonne de texte qui suit motif
numéro après MS, HS et XP, numéro après TANK et numéro après Tank_
ID text new_text 0 1 T7MS1 1 1 2 T5HS2 2 2 3 T3XP1 1 3 4 Tank_3 3 4 5 TANK 5 5 5 6 System SystemOutput
t['text'].apply(lambda x: re.findall(r'(?:MS|HS|XP|TANK |Tank_)(\d+)', x)[0] if re.findall(r'(?:MS|HS|XP|TANK |Tank_)(\d+)', x) else x)Updated
Utilisation de alexis regex
ID text new_text 0 1 T7MS1 1 1 2 T5HS2 2 2 3 T3XP1 1 3 4 Tank_3 3 4 5 TANK 5 5Sortie
l = ['MS','HS','XP','TANK','Tank_'] t['new_text'] = t['text'].apply(lambda x: re.findall(r'(?<=[{}\s])\d'.format( [d for d in l if d in x][0]),x)[0])
Utilisez l'expression régulière suivante pour combiner tous les préfixes:
(?:MS|HS|XP|TANK |Tank_)(\d+)
Puisque j'ai utilisé un "groupe non capturant" (?:) pour les préfixes, votre le numéro cible est toujours dans le groupe 1, comme dans votre code.
le nombre est-il toujours le dernier caractère?
Il semble que les réponses ci-dessous fonctionnent pour vous. Veuillez envisager d'accepter le meilleur. Si vous avez besoin d'aide supplémentaire, faites-le savoir.
Réponse mise à jour.