Python 使用正则表达式替换DataFrame中的列
我有一个4列的数据框,col4是一个包含文本和数字的字符串:Python 使用正则表达式替换DataFrame中的列,python,pandas,Python,Pandas,我有一个4列的数据框,col4是一个包含文本和数字的字符串: Col1 Col2 Col3 Col4 Syslog 2016,09,17 1 PD380_003 %LINK-3-UPDOWN Syslog 2016,09,17 1 NM380_005 %BGP-5-NBR_RESET Syslog 2016,09,14
Col1 Col2 Col3 Col4
Syslog 2016,09,17 1 PD380_003 %LINK-3-UPDOWN
Syslog 2016,09,17 1 NM380_005 %BGP-5-NBR_RESET
Syslog 2016,09,14 1 NM380_005 %BGP-5-NBR_RESET
Syslog 2016,09,08 1 DO NOT TICKET LO380_004 %SYS-5-CONFIG_I Config
我需要保留该列的子字符串并删除任何其他内容,因此我使用了regex并创建了一个模式,但当我运行以下查询时,结果不是我想要的,它会用模式本身替换所有内容:
data.replace({'Col4':{'.*':'([A-Z]{2}[0-9]{3}_[0-9]{3})'}},regex=True)
预期结果是:
Col1 Col2 Col3 Col4
Syslog 2016,09,17 1 PD380_003
Syslog 2016,09,17 1 NM380_005
Syslog 2016,09,14 1 LO380_004
Syslog 2016,09,08 1 LO380_004
但我得到的结果是:
Col1 Col2 Col3 Col4
Syslog 2016,09,17 1 ([A-Z]{2}[0-9]{3}_[0-9]{3})
Syslog 2016,09,17 1 ([A-Z]{2}[0-9]{3}_[0-9]{3})
Syslog 2016,09,14 1 ([A-Z]{2}[0-9]{3}_[0-9]{3})
Syslog 2016,09,08 1 ([A-Z]{2}[0-9]{3}_[0-9]{3})
我做错了什么?我想你需要:
你用的正则表达式是错误的
{'Col4':{'.*':'([A-Z]{2}[0-9]{3}{[0-9]{3}}}
-表示将Col4
列中的任何字符串替换为([A-Z]{2}[0-9]{3}[0-9]{3})
试试这个:
In [87]: df.replace({'Col4':{r'.*?([A-Z]{2}[0-9]{3}_[0-9]{3}).*':r'\1'}}, regex=True)
Out[87]:
Col1 Col2 Col3 Col4
0 Syslog 2016,09,17 1 PD380_003
1 Syslog 2016,09,17 1 NM380_005
2 Syslog 2016,09,14 1 NM380_005
3 Syslog 2016,09,08 1 LO380_004
首先,你在错误的位置有错误的正则表达式。要替换的
参数需要匹配要替换的内容和要删除的内容。因此,在这种情况下,您需要在正则表达式前面加一个^..*
,在正则表达式后面加一个*$
,因为您希望在匹配之外修剪字符串:
^.*([A-Z]{2}[0-9]{3}_[0-9]{3}).*$
其次,如果是正则表达式,replace
参数需要是捕获组或固定字符串。在这种情况下,\1
就可以了
最后,.replace
的系列形式有一个更简单的语法(至少对我来说)来理解
因此:
>>> df
Col1 Col2 Col3 Col4
0 SysLog 2016,09,17 1 PD380_003 %LINK-3-UPDOWN
1 SysLog 2016,09,17 1 NM380_005 %BGP-5-NBR_RESET
2 SysLog 2016,09,17 1 NM380_005 %BGP-5-NBR_RESET
3 SysLog 2016,09,17 1 DO NOT TICKET LO380_004 %SYS-5-CONFIG_I Config
你可以做:
>>> df['Col4'].replace(to_replace='^.*([A-Z]{2}[0-9]{3}_[0-9]{3}).*$', value=r'\1', regex=True)
0 PD380_003
1 NM380_005
2 NM380_005
3 LO380_004
Name: Col4, dtype: object
如果更容易,也可以使用位置参数版本:
df['Col4'].replace('^.*([A-Z]{2}[0-9]{3}_[0-9]{3}).*$', r'\1', regex=True)
但是您需要使用regex=True
,因为替换字符串将被解释为regex,而不仅仅是静态字符串
最后,将以下内容直接分配到原始文件中:
>>> df['Col4']=df['Col4'].replace('^.*([A-Z]{2}[0-9]{3}_[0-9]{3}).*$', r'\1', regex=True)
>>> df
Col1 Col2 Col3 Col4
0 SysLog 2016,09,17 1 PD380_003
1 SysLog 2016,09,17 1 NM380_005
2 SysLog 2016,09,17 1 NM380_005
3 SysLog 2016,09,17 1 LO380_004
你能在替换之前发布你的数据DF吗?是的,请再次检查。是的,它可以工作,但我只是想知道为什么替换不能读取正则表达式?嗯,我检查了,它可以工作。但我认为这是错误。感谢解释我是新来的熊猫这个解释的孩子帮助:)
>>> df['Col4']=df['Col4'].replace('^.*([A-Z]{2}[0-9]{3}_[0-9]{3}).*$', r'\1', regex=True)
>>> df
Col1 Col2 Col3 Col4
0 SysLog 2016,09,17 1 PD380_003
1 SysLog 2016,09,17 1 NM380_005
2 SysLog 2016,09,17 1 NM380_005
3 SysLog 2016,09,17 1 LO380_004