【问题标题】:replacing a column in DataFrame using regex使用正则表达式替换 DataFrame 中的列
【发布时间】:2016-10-11 05:17:18
【问题描述】:

我有一个 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           1    NM380_005 %BGP-5-NBR_RESET
Syslog        2016,09,08           1    DO NOT TICKET LO380_004 %SYS-5-CONFIG_I Config

我需要保留该列的子字符串并删除其他任何内容,因此我使用了正则表达式并创建了一个模式,但是当我运行以下查询时,结果不是我想要的,它将所有内容都替换为模式本身:

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})

我做错了什么?

【问题讨论】:

  • 你能在替换之前发布你的dataDF吗?
  • 是的,请再次查看。

标签: python pandas


【解决方案1】:

首先,您在错误的位置使用了错误的正则表达式。 .replaceto_replace 参数需要匹配要替换的内容和要删除的内容。因此,在这种情况下,您需要在正则表达式前面加上 ^.*,在正则表达式后面加上 .*$,因为您想修剪匹配之外的字符串:

^.*([A-Z]{2}[0-9]{3}_[0-9]{3}).*$

Demo

其次,replace 参数,如果是正则表达式,则需要是捕获组或固定字符串。在这种情况下,\1 可以。

最后,.replace 的 Series 形式具有更简单的语法(至少对我而言)易于理解。

所以给定:

>>> 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,因为替换字符串将被解释为正则表达式——而不仅仅是静态字符串。

最后直接赋值到原来的:

>>> 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

【讨论】:

  • 感谢您解释我是熊猫的新手,这个解释帮助的孩子:)
【解决方案2】:

我觉得你需要extract:

data.Col4 = data.Col4.str.extract('([A-Z]{2}[0-9]{3}_[0-9]{3})', expand=False)

print (data)
     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

【讨论】:

  • 是的,它可以工作,但我只是想知道为什么替换无法读取正则表达式?
  • 嗯,我检查了docs,它可以工作。
  • 但我认为这是错误。
【解决方案3】:

您以错误的方式使用 RegEx。

{'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

【讨论】:

    猜你喜欢
    • 2020-07-16
    • 2014-03-29
    • 1970-01-01
    • 2019-01-24
    • 1970-01-01
    • 2015-12-05
    • 2020-11-05
    • 2014-06-01
    • 1970-01-01
    相关资源
    最近更新 更多