【问题标题】:Pattern Matching Error in Python Using Pandas.series.str.contains for String ReplacementPython 中使用 Pandas.series.str.contains 进行字符串替换的模式匹配错误
【发布时间】:2019-01-18 16:05:12
【问题描述】:

我正在尝试用从包含多组括号的字典中提取的字符串替换熊猫数据框中的字符串。运行脚本时,匹配组出现错误,并且字符串未被替换。我相当确信这个错误是由括号引起的。

为了解决这个问题,我一直在尝试使用 str.contains() 方法使用正则表达式模式匹配。我已经查看了 stackoverflow 上提供的其他解决方案,但未能成功解决我的错误。

这是我用于测试目的的一些脚本。在字符串中保留括号很重要(即我不必删除它们):

import pandas as pd
import numpy as np

dict= {'2017() (pat)':'2000',
       '2018() (pat)':'2001'}

df = pd.DataFrame({'YEAR': ['test2017end','test2018end','test2019end'],
                   'MONTH': ['Jan','Feb','Mar'],
                   'DD': ['1','12','22']})

for init, repl in dict.items():
    df.loc[df['YEAR'].str.contains(init),'YEAR'] = repl

print(df)

有人可以提供有关使用模式匹配的指导,以便正确替换字符串吗?

谢谢!

【问题讨论】:

  • 不要给字典命名dict

标签: python pandas numpy replace pattern-matching


【解决方案1】:

不要使用变量dict,因为python代码关键字。

解决方案是提取字典键中的第一个整数:

import re

d= {'2017() (pat)':'2000',
       '2018() (pat)':'2001'}

df = pd.DataFrame({'YEAR': ['test2017end','test2018end','test2019end'],
                   'MONTH': ['Jan','Feb','Mar'],
                   'DD': ['1','12','22']})

for init, repl in d.items():
    i = re.findall('\d+', init)[0]
    df.loc[df['YEAR'].str.contains(i),'YEAR'] = repl

print(df)
          YEAR MONTH  DD
0         2000   Jan   1
1         2001   Feb  12
2  test2019end   Mar  22

【讨论】:

    【解决方案2】:

    您是否尝试过不涉及循环的方法?这个方向的东西:

    import re
    import pandas as pd
    
    dict_= {'2017() (pat)':'2000',
           '2018() (pat)':'2001'}
    
    df = pd.DataFrame({'YEAR': ['test2017end','test2018end','test2019end'],
                       'MONTH': ['Jan','Feb','Mar'],
                       'DD': ['1','12','22']})
    
    pat = r'(\d{4,4})'
    
    dict_b = {re.search(pat, key).group(1):item for key, item in dict_.items()}
    
    # Return NaN for no match
    df['YEARX'] = df['YEAR'].str.extract(pat,expand=False).map(dict_b)
    
    # Return found year for no match
    df['YEARY'] = df['YEAR'].str.extract(pat,
                      expand=False).apply(lambda x: dict_b[x] if x in dict_b.keys() else x)
    

    【讨论】:

      【解决方案3】:

      感谢您的快速回复。我的代码比我发布的要复杂一些,实际上我匹配的是字符而不是数字。我为此修改了 jerzael 的响应,并且脚本正常运行。这是我使用的测试脚本:

      import pandas as pd
      import numpy as np
      import re
      
      dct= {'love (one)()':'john',
             'smith (two)()':'doe',
             'ken (three)()':'yearns'}
      
      df = pd.DataFrame({'MAN': ['test|smith (two)()end','test|love (one)()end','test|ken (three)()end'],
                         'MONTH': ['Jan','Feb','Mar'],
                         'DD': ['1','12','22']})
      
      for init, repl in dct.items():
          i = re.findall(r'\w+', init)[0]
          df.loc[df['MAN'].str.contains(i),'MAN'] = repl
      
      print(df)
      

      对于像我这样的初学者来说,正则表达式如何文档是必须的(https://docs.python.org/3/howto/regex.html#regex-howto

      干杯

      【讨论】:

        猜你喜欢
        • 2014-09-03
        • 2022-01-02
        • 2016-06-17
        • 2021-01-26
        • 1970-01-01
        • 2014-08-20
        • 2013-09-08
        • 1970-01-01
        • 2013-10-24
        相关资源
        最近更新 更多