代码之家  ›  专栏  ›  技术社区  ›  oymonk

如何从候选列表中识别包含最少数量不同单词的行?

  •  -1
  • oymonk  · 技术社区  · 3 年前

    我有一个单词列表和一个数据集。我想确定数据集中至少有两个单词在列表中的行。

    我能够识别至少包含两个列表词的行,但我的代码也有问题地识别重复单个列表词的行。

    这是我的密码:

    import pandas as pd
        
    data={'Name':['Redred','redblue','redgreen','blue']}
    
    df=pd.DataFrame(data)
    
    df['Good colours'] = (df['Name'].str.contains("(red.*|blue.*|green.*){2,}",case=False, regex=True))
    
    print(df)
    

    为了排除重复的单词,我尝试了 (red.*){1,}(blue.*){1,}(green.*){1}

    如何编写正则表达式,以便它识别列表词的两个实例,同时排除列表词的重复实例?

    2 回复  |  直到 3 年前
        1
  •  0
  •   Wiktor Stribiżew    3 年前

    (df['Name'].str.contains(r"^(?!(red|blue|green)\1+$)(?:.*(?:red|blue|green)){2}",case=False, regex=True))
    

    如果字符串必须仅由列表中的单词组成,请删除 .* {2} 具有 {2,}$

    (df['Name'].str.contains(r"^(?!(red|blue|green)\1+$)(?:red|blue|green){2,}$",case=False, regex=True))
    

    细节

    • ^
    • (?!(red|blue|green)\1+$) -如果存在,则会导致比赛失败的消极前瞻
      • (red|blue|green) -组1:组中定义的任何子字符串
      • \1+ -一次或多次重复第1组值,然后
      • $ -结束
    • (?:.*(?:red|blue|green)){2} -两次出现除换行符以外的零个或多个字符(尽可能多),然后一次出现组中定义的子字符串。
    • (?:red|blue|green){2,}$ -组中的单词出现两次或两次以上,然后是字符串结尾。

    regex demo #1 regex demo #2 .

        2
  •  0
  •   Karl Knechtel    3 年前

    有时候正则表达式不是完成这项工作的工具。

    def name_has_color(df, color):
        return df['Name'].str.contains(color, case=False).astype(int)
    
    color_counts = sum(
        name_has_color(df, color)
        for color in ['red', 'green', 'blue']
    )
    
    df['good_colors'] = df[color_counts >= 2]
    

    这种方法自然是可扩展的,如果您需要检查更多的包含值或查找更多的值,则不会变得更复杂。