J'essaie d'extraire le modèle de chaîne de plusieurs colonnes dans une seule colonne de résultat en utilisant Pandas et str.extract.

Mon exemple de trame de données est le suivant.

field1   field2
ab1234   ab1234
ac1234   
qw45     rt23
c1234b   cb1234
cv       1234dd
...

Je veux extraire le '1234' (EDIT: tout entier à 4 chiffres et pas seulement '1234') de l'une ou l'autre colonne (champ1 et champ2 dans ce cas) dans une nouvelle colonne de résultat pour obtenir le résultat souhaité ci-dessous

field1   field2   result
ab1234   ab1234   1234
ac1234            1234
qw45     rt23     
c1234b   cb1234   1234
cv       1234dd   1234
...

J'essaie d'utiliser pandas str.extract pour obtenir le résultat souhaité, mais je n'ai pas réussi comme suit.

import pandas as pd
import numpy as np
import re


df = pd.DataFrame({'field1':['ab1234','ac1234','qw45', 'c1234b', 'cv'], 
'field2':['ab1234','','rt23','cb1234', '1234dd']})

df['result'] = df[['field1', 'field2']].apply(lambda x: 
x.str.extract(r'(\d{4})', flags = re.IGNORECASE, expand = 
False)).any(axis=1)

print(df)

Ce qui précède ne renvoie que des résultats booléens. Je me demande si ce qui précède peut être converti pour retourner le modèle réel ou existe-t-il d'autres moyens de résoudre ce problème?

Merci beaucoup d'avance.

EDIT: Désolé, je dois mentionner que le modèle peut être un entier à 4 chiffres, pas seulement «1234». Ainsi, je veux que la colonne de résultat renvoie ces 4 chiffres.

2
nqcthanh 16 mars 2019 à 01:50

2 réponses

Meilleure réponse

IIUC

df['New']=df.apply(','.join,axis=1).str.extract(r'(\d{4})', expand = 
False).fillna('')
df
   field1  field2   New
0  ab1234  ab1234  1234
1  ac1234          1234
2    qw45    rt23      
3  c1234b  cb1234  1234
4      cv  1234dd  1234
1
BENY 16 mars 2019 à 00:29

Vous y étiez presque, vous pouvez faire ce qui suit. Nous pouvons utiliser un for loop pour appliquer str.extract deux fois afin de créer deux colonnes temporaires.

Après cela, créez la dernière colonne result avec fillna.

cols = ['field1', 'field2']
n=1
for col in cols:
    df['result'+str(n)] = df[col].str.extract('([0-9]{4})')
    n += 1

df['result'] = df.result1.fillna(df.result2).fillna('')
df.drop(['result1', 'result2'], inplace=True, axis=1)

print(df)
   field1  field2 result
0  ab1234  ab1234   1234
1  ac1234           1234
2    qw45    rt23       
3  c1234b  cb1234   1234
4      cv  1234dd   1234  
1
Erfan 15 mars 2019 à 23:54