【问题标题】:remove item from list if it does not match substring, regardless of the formatting如果项目与子字符串不匹配,则从列表中删除项目,无论格式如何
【发布时间】:2020-07-18 09:46:44
【问题描述】:

我有以下数据框:

df = pd.DataFrame()
df['full_string'] = [['apples and bananas', 'applesandbananasamongstothers', 'something else'], 
          ['ApplesandBananas', 'apples and Bananas', 'bananas']]
df['substring'] = ['apples and bananas', 'apples and bananas']

期望的结果是保留 df['full_string'] 中包含在 df['substring'] 中找到的文本的项目,同时考虑到:

  • 大小写大小写无关紧要
  • 单词之间的间距
  • 单词可能包含与 df['substring'] 中的文本无关的其他文本

期望的结果:

df['outcome'] = [['apples and bananas', 'applesandbananasamongstothers'], 
      ['ApplesandBananas', 'apples and Bananas', 'bananas']]

我尝试的是让 df['substring'] 的第一个关键字将其用作 df['full_string'] 的匹配器,但是,这不允许我在数据框的第二行。

这不适用于虚拟数据):

first_keyword = []
for i in df['substring']:
    first_keyword.append(i.split(' ', 1)[0])

df['first_keyword'] = first_keyword

df['C'] = [x[0].lower() in (x[1].lower()) for x in zip(df['first_keyword'], df['full_string'])]

【问题讨论】:

    标签: python string substring matching


    【解决方案1】:

    为了简化示例,我选择使用包含您的虚拟数据的列表。你需要让它适应你的问题。 此外,我将您的句子“期望的结果是保留 df['full_string'] 中包含 df['substring'] 中的文本的项目”解释为 text = word。

    full_str = ['apples and bananas', 'applesandbananasamongstothers', 'something else', 
               'ApplesandBananas', 'apples and Bananas', 'bananas']
    sub_str = ['apples and bananas', 'red and blue']
    
    # Extract words from sub strings
    words_in_sub = [elt.split() for elt in sub_str]
    # Flatten and remove duplicates
    words_in_sub = list(set([item for sublist in words_in_sub for item in sublist]))
    
    # Init output
    output = list()
    # Loop on the strings in full string
    for full_s in full_str:
        # Loop on the words to look for
        for word in words_in_sub:
            if word.lower() in full_s.lower():
                output.append(full_s)
                break
    

    输出:

    In: output
    Out: 
    ['apples and bananas',
     'applesandbananasamongstothers',
     'ApplesandBananas',
     'apples and Bananas',
     'bananas']
    

    在 if 条件中处理小写/大写。间距由in 语句处理。 full_s 中其他文本的存在由 in 语句处理。如果单词出现在字符串中的某处,in 语句将返回 True。当单词可能被认为存在于字符串中时,它会返回 False 的唯一情况是单词被空格分成两个,例如'bana naan dapp les'。此示例不会保留在输出列表中。

    编辑:多行。您也可以将列表展平并使用第一个代码。

    full_str = [['apples and bananas', 'applesandbananasamongstothers', 'something else'], 
                ['ApplesandBananas', 'apples and Bananas', 'bananas']]
    sub_str = [['apples and bananas'], ['apples and bananas']]
    
    # Assuming same number of rows between full_str and sub_str
    # And you want to keep element of full_str[k] according to sub strings in sub_str[k]
    number_of_rows = len(full_str)
    for k in range(number_of_rows):
        # Extract words from sub strings
        words_in_sub = [elt.split() for elt in sub_str[k]]
        # Flatten and remove duplicates
        words_in_sub = list(set([item for sublist in words_in_sub for item in sublist]))
    
        # Init output
        output = list()
        # Loop on the strings in full string
        for full_s in full_str[k]:
            # Loop on the words to look for
            for word in words_in_sub:
                if word.lower() in full_s.lower():
                    output.append(full_s)
                    break
    

    【讨论】:

    • 感谢您快速而详尽的回复。这绝对有帮助,我可以适应我的问题。我正在努力解决的唯一修改不是返回输出列表,而是过滤包含“匹配”的行。以您的虚拟数据为例,full_str 和 sub_str 的列表在字符串匹配之前和之后的长度相同。
    • @bjornvandijkman 我不明白您所说的“full_str 和 sub_str 的列表在字符串匹配之前和之后的长度相同”是什么意思。 full_str 有 6 个元素,而列表 sub_str 只有 2 个。
    • 在我的虚拟数据中,完整字符串和子字符串两列都有 2 行。从第一行开始,我想从“完整字符串”中删除“其他内容”,同时保留其他内容。在第二行中,我想将所有元素保留在“整行”中。因此,输入和输出数据帧都将包含 2 行(少 1 个元素)。
    • @bjornvandijkman 然后只需在行上再添加一个 for 循环并一一处理。结构为for r in rows: for full_s in full_str: for words in words_in_sub:。我认为必须有一种更直接和矢量化的方式来直接在 pandas 中执行您想要的操作,但是如果您的数据框不是太大,那么简单的 for 循环实现就足够了。我将编辑我的示例以在子字符串上添加这个 + 循环。
    • @bjornvandijkman 我选择稍微修改sub_str,因为在您的示例中我不明白为什么将其定义为df['substring'] = ['apples and bananas', 'apples and bananas']。您将其定义为具有两次相同元素的列表。相反,我决定将其定义为列表列表,包含 2 行,每行都有相同的元素。
    猜你喜欢
    • 2023-04-07
    • 1970-01-01
    • 2012-03-12
    • 1970-01-01
    • 2021-11-12
    • 2020-11-11
    • 1970-01-01
    • 2015-05-25
    • 1970-01-01
    相关资源
    最近更新 更多