【问题标题】:Detect specific sequence of string in a column from a list从列表中检测列中的特定字符串序列
【发布时间】:2019-08-11 23:30:55
【问题描述】:

我正在尝试使用列表提取特定字符串。这在 Python 中可行吗?

我有这个列表:

currency = ['SGD', 'GBP', 'USD', 'EUR']

如果这些字符串中的任何一个出现在列中,我希望使用相应的货币创建一个新列。这是我的预期输出:

预期输出

Name         Currency        Currency_updated    
0   Tom    RANDOM_SGD_2017         SGD
1   nick    TEST_EUR_1381          EUR
2   krish   FORFUN GBP             GBP
3   jack    NAs                    <blank>

可重现的示例

import pandas as pd 

data = {'Name':['Tom', 'nick', 'krish', 'jack'], 'Currency':['RANDOM_SGD_2017', 'TEST_EUR_1381', 'FORFUN GBP', 'NAs']} 

df = pd.DataFrame(data) 

使用的数据框

     Name       Currency
0   Tom RANDOM_SGD_2017
1   nick    TEST_EUR_1381
2   krish   FORFUN GBP
3   jack    NAs

【问题讨论】:

  • 如果您不想在 EUROPE 中匹配 EUR,请参阅 my answer

标签: python regex pandas


【解决方案1】:

另一种方法是使用re.search()

import re
df['Currency_updated'] = df['Currency'].apply(lambda x: re.search('|'.join(currency), x).group(0) if x!='NAs' else None)

【讨论】:

    【解决方案2】:

    我建议使用str.extract

    (?<![^\W_])(SGD|GBP|USD|EUR)(?![^\W_])
    

    请参阅regex demo

    请注意,(?&lt;![^\W_]) / (?![^\W_]) 是明确的单词边界,也将_(下划线)视为“非单词”字符,因此_EUR_ 中的EUR 被视为整个单词。

    在 Python 中,可以使用 r'(?&lt;![^\W_])({})(?![^\W_])'.format('|'.join(map(re.escape, currency)))re.escape 构建正则表达式,以防万一货币名称中可能包含 $ 或其他特殊字符,例如 CA$

    import re
    import pandas as pd
    
    data = {'Name':['Tom', 'nick', 'krish', 'jack', 'meg', 'sarah'], 'Currency':['RANDOM_SGD_2017', 'TEST_EUR_1381', 'FORFUN GBP', 'NAs', 'More fun in EUROPE', 'And MUSDA thing']}
    currency = ['SGD', 'GBP', 'USD', 'EUR']
    df = pd.DataFrame(data)
    
    rx = r'(?<![^\W_])({})(?![^\W_])'.format('|'.join(map(re.escape, currency)))
    df['Currency_updated'] = df['Currency'].str.extract(rx, expand=False)
    

    输出:

    >>> df
        Name            Currency Currency_updated
    0    Tom     RANDOM_SGD_2017              SGD
    1   nick       TEST_EUR_1381              EUR
    2  krish          FORFUN GBP              GBP
    3   jack                 NAs              NaN
    4    meg  More fun in EUROPE              NaN
    5  sarah     And MUSDA thing              NaN
    

    【讨论】:

      【解决方案3】:

      Series.str.extractjoin| 一起用于正则表达式OR - 'SGD|GBP|USD|EUR' 表示'SGD' or 'GBP' or 'USD' or 'EUR'

      pat = '|'.join(currency)
      df['Currency_updated'] = df['Currency'].str.extract('('+ pat + ')', expand=False)
      print (df)
          Name         Currency Currency_updated
      0    Tom  RANDOM_SGD_2017              SGD
      1   nick    TEST_EUR_1381              EUR
      2  krish       FORFUN GBP              GBP
      3   jack              NAs              NaN
      

      【讨论】:

      • 谢谢你的回答,请问你为什么用'|'在你的第一行?它有什么作用?
      【解决方案4】:

      您可以创建一个对数据框的行进行操作的函数:

      import pandas as pd
      
      def f(row):
        for elem in currency:
            if elem in row['Currency']:
                 return elem
      
      currency = ['SGD', 'GBP', 'USD', 'EUR']
      data = {'Name':['Tom', 'nick', 'krish', 'jack'], 'Currency':['RANDOM_SGD_2017', 'TEST_EUR_1381', 'FORFUN GBP', 'NAs']}
      
      df = pd.DataFrame(data)
      df['Currency_Updated'] = df.apply(f, axis=1)
      print(df)
      

      输出

          Name         Currency Currency_Updated
      0    Tom  RANDOM_SGD_2017              SGD
      1   nick    TEST_EUR_1381              EUR
      2  krish       FORFUN GBP              GBP
      3   jack              NAs             None
      

      【讨论】:

      • @Javier 不客气,你可以接受对你有帮助的答案,干杯!
      猜你喜欢
      • 2019-09-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-07-02
      • 2015-11-23
      • 1970-01-01
      • 1970-01-01
      • 2013-04-07
      相关资源
      最近更新 更多