Je tente de remplir une colonne dans un Pandas.DataFrame
en extrayant l'id
d'un périphérique à partir d'un fichier journal. Le problème est que l'id
peut être précédé de deux motifs distincts comme suit :
Motif 1:
(?<=cameraId=\')([a-z0-9-]+))
Motif 2:
(?<=/live/)([a-z0-9-]+)
Remarque : il n'y a pas de moyen pour une ligne d'avoir les deux motifs
Le problème est que j'utilise la méthode Pandas.String.str.findall()
, et je veux que les deux motifs soient remplis.
Je peux obtenir le résultat souhaité avec succès comme le montre le code ci-dessous :
import pandas as pd
line_1 = 'INFO:2021-04-19 00:25:10,647:instance_manager.py:MainProcess:1:got event notificationName=\'DETECTION_STARTED\' cameraId=\'ab1c-ab6c-a6f6-a6d6-ab666\' timestamp=\'2021-04-19T00:24:08.192169Z\''
line_2 = 'INFO:2021-04-19 00:25:11,278:instance_manager.py:MainProcess:1:An old record record for the stream rtsp://127.0.1.1:6666/live/a001-a00a-0016-a006-ab606.stream was successfully updated in the DB!'
df = pd.DataFrame(columns=['type', 'ts', 'process', 'subprocess', 'line', 'message'])
line_1_parsed = pd.Series([line_1]).str.extract(r'(?P[^:]+):(?P.+,\d+):(?P[^:]+):(?P[^:]+):(?P[^:]+):(?P[^$]+)')
line_2_parsed = pd.Series([line_2]).str.extract(r'(?P[^:]+):(?P.+,\d+):(?P[^:]+):(?P[^:]+):(?P[^:]+):(?P[^$]+)')
df =df.append(line_1_parsed, ignore_index=True)
df =df.append(line_2_parsed, ignore_index=True)
df.loc[:, 'cam_id'] = df.loc[:, 'message'].str.findall('(?<=cameraId=\')([a-z0-9-]+)|(?<=/live/)([a-z0-9-]+)')
df
, mais ils sont retournés sous forme de tuples (motif 1, motif 2) comme indiqué dans la Sortie actuelle
:
Sortie actuelle:
type ts process subprocess line message cam_id
0 INFO 2021-04-19 00:25:10,647 instance_manager.py MainProcess 1 got event notificationName='DETECTION_STARTED'... [(ab1c-ab6c-a6d6-ab666, )]
1 INFO 2021-04-19 00:25:11,278 instance_manager.py MainProcess 1 An old record record for the stream rtsp://127... [(, a001-a00a-0016-a006-ab606)]
Je comprends que cela est dû au fait qu'il essaie les deux motifs et renvoie les correspondances pour les deux, mais je préférerais qu'il n'y ait que le motif réussi.
Je peux le faire en extrayant manuellement de la manière suivante :
df.loc[:, 'cam_id'] = df.loc[:, 'cam_id'].apply(lambda cam_id_tuple: cam_id_tuple[0][0] if cam_id_tuple[0][0] != '' else cam_id_tuple[0][1])
df
mais c'est plutôt une solution fastidieuse, et non extensible, au cas où je voudrais ajouter des motifs.
Sortie souhaitée:
type ts process subprocess line message cam_id
0 INFO 2021-04-19 00:25:10,647 instance_manager.py MainProcess 1 got event notificationName='DETECTION_STARTED'... [ab1c-ab6c-a6d6-ab666]
1 INFO 2021-04-19 00:25:11,278 instance_manager.py MainProcess 1 An old record record for the stream rtsp://127... [a001-a00a-0016-a006-ab606]`
Nonte: la colonne cam_id
contient des chaînes de caractères et non des tuples
Merci d'avance.