【问题标题】:apply condition on column1 where string contains only given set of keywords rather contains give set of keywords在 column1 上应用条件,其中字符串仅包含给定的关键字集,而不是包含给定的关键字集
【发布时间】:2020-10-25 03:49:46
【问题描述】:

如何在 column1 上应用条件,其中字符串 仅包含 给定一组关键字,而不是 包含 给定一组关键字。 强调“仅”这个词

import pandas as pd
import numpy as np
import re

d = {'_id': [1, 2, 3, 4, 5, 6, 7],
     'column1': ['FullName', 'custfullnm', 'nm123', 'sitenm', 'full12', 'suplnm', 'countryfulln'],
     'column2': ['', '', '', '', '', '', '']}

df = pd.DataFrame(data=d)


key_words = ["full", "nm", "name", "txt", "[0-9]"]

check = f"{'|'.join(key_words)}"

mand_key = "full"

df["column2"] = np.where(
    df.column1.str.contains(mand_key, case=False)
    & (df.column1.str.contains(check, case=False, regex=True)),
    "Full Name",
    "",
)

想要的输出:

_id,column1,column2
1,FullName,Full Name
2,custfullnm,
3,nm123,
4,sitenm,
5,full12,Full Name
6,suplnm,
7,countryfullnm,

只有 FullName, full12 符合条件,原因如下:

FullName is only made of words from given set of keywords 'full' & 'name'
full12 is only made of words from given set of keywords 'full' & a number '12'

而rest不符合条件,原因如下:

custfullnm      contains 'cust' not in given list of keywords though contains 'nm' & 'full'
nm123           dones't contain madate keyword 'full' though contains a number & 'nm'
sitename        contains 'site' not in given list of keywords though contains 'name'
suplnm          contains 'supl' not in given list of keywords though contains 'nm'
countryfullnm       contains 'country' not in given list of keywords though contains 'nm' & 'full'

【问题讨论】:

    标签: python regex pandas numpy


    【解决方案1】:

    我自己得到了答案:

    key_words = ["full", "nm", "name", "txt", "[0-9]"]
    check = f"{'|'.join(key_words)}"
    mand_key = "full"
    df["column2"] = np.where(
        df.column1.str.contains(mand_key, flags=re.IGNORECASE)
        & df.column1.str.match(check, flags=re.IGNORECASE),"Full Name","",)
    df
    

    【讨论】:

    • 但这仍然不适用于 column1 值“fullphotourl”
    • 这是因为'|'.join(key_words) 只匹配任何替代项的任何一次出现,而match 要求匹配出现在字符串的开头,但不需要完整的字符串匹配。因此,您匹配所有包含 mand_key 的条目,并且在字符串开头是来自 key_words 的子模式
    • 你说得对,我是在更大的数据集上运行代码后才知道这一点的。
    【解决方案2】:

    您可以创建一个模式,该模式将从字符串开头开始匹配任意数量的允许子模式,然后尝试匹配您的强制键,然后再次允许任意数量的指定子模式,直到结束字符串:

    import pandas as pd
    import numpy as np
    import re
    
    d = {'_id': [1, 2, 3, 4, 5, 6, 7, 8],
         'column1': ['FullName', 'custfullnm', 'nm123', 'sitenm', 'full12', 'suplnm', 'countryfulln', np.NaN],
         'column2': ['1', '2', '3', '4', '5', '6', '7', '8']}
    
    df = pd.DataFrame(data=d)
    
    key_words = ["full", "nm", "name", "txt", "[0-9]"]
    mand_key = "full"
    check = rf'^(?:{"|".join(key_words)})*{mand_key}(?:{"|".join(key_words)})*$'
    df["column2"] = np.where(df["column1"].str.contains(check, case=False, na=True),"Full Name","")
    

    输出:

    >>> df
       _id       column1    column2
    0    1      FullName  Full Name
    1    2    custfullnm           
    2    3         nm123           
    3    4        sitenm           
    4    5        full12  Full Name
    5    6        suplnm           
    6    7  countryfulln           
    7    8           NaN  Full Name
      
    

    图案看起来像

    ^(?:full|nm|name|txt|[0-9])*full(?:full|nm|name|txt|[0-9])*$
    

    regex demo

    详情

    • ^ - 字符串开头
    • (?:full|nm|name|txt|[0-9])* - 指定子模式的 0 次或多次重复
    • full - 强制密钥
    • (?:full|nm|name|txt|[0-9])* - 指定子模式的 0 次或多次重复
    • $ - 字符串结束。

    【讨论】:

    • 完美!我们需要处理异常,如果值为“NA”,则将其视为匹配项。只需添加一个项目“NA”并尝试相同的代码。
    • @Achar007 添加na=True, df["column2"] = np.where(df["column1"].str.contains(check, case=False, na=True),"Full Name","")
    • 您好,根据您的建议,在包含 na=True 后,我已在您的回答中添加了 I/P 和 O/P
    • @Achar007 它有效。在column1 中所有等于np.NaN 的条目,在结果column2 中有Full Name。查看更新的演示。
    • @Achar007 如果column1中的值为np.NaN,我们告诉pandas使用na=True返回True,因此,then部分被触发,即返回Full Name。您不能将 NaN 值与正则表达式匹配。正则表达式只对字符串类型起作用。
    猜你喜欢
    • 2011-03-18
    • 2014-11-06
    • 2023-03-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-09-20
    • 2012-02-25
    • 1970-01-01
    相关资源
    最近更新 更多