python - 匹配 DataFrame 列中字符串中的独立单词

标签 python regex pandas dataframe

我有一个数据框,例如:

import pandas as pd
import re

df = pd.DataFrame({"Name": ["D1", "D2", "D3", "D4", "M1", "M2", "M3"], 
                  "Requirements": ["3 meters|2/3 meters|3.5 meters",
                                   "3 meters",
                                   "3/5 meters|3 meters",
                                   "2/3 meters",
                                   "steel|g1_steel",
                                   "steel",
                                   "g1_steel"]})

数据框 df

  Name                    Requirements
0   D1  3 meters|2/3 meters|3.5 meters
1   D2                        3 meters
2   D3             3/5 meters|3 meters
3   D4                      2/3 meters
4   M1                  steel|g1_steel
5   M2                           steel
6   M3                        g1_steel

我有一个单词列表 req_list = ['3 metres', 'steel'],我正在尝试从 df 中提取行,其中列中的字符串 Requirements 包含来自 req_list 的独立单词。这就是我所做的:

这个仅打印 D2 和 M2

df[df.Requirements.apply(lambda x: any(len(x.replace(y, '')) == 0 for y in req_list))]

此打印所有行

df[df['Requirements'].str.contains(fr"\b(?:{'|'.join(req_list)})\b")]

我想要的结果如下:

  Name                    Requirements
0   D1  3 meters|2/3 meters|3.5 meters
1   D2                        3 meters
2   D3             3/5 meters|3 meters
4   M1                  steel|g1_steel
5   M2                           steel

在此所需的输出中,D4 和 M3 被消除,因为它们没有来自 req_list 的单词作为独立字符串。有没有什么方法可以在不使用自定义函数的情况下最好地在一行中实现这一目标?

编辑

Requirements 列中的字符串可以采用任何模式,例如:

    Name                    Requirements
0   D1    3 meters|2/3 meters|3.5 meters
1   D2                          3 meters
2   D3               3/5 meters|3 meters
3   D4                        2/3 meters
4   D5                       3::3 meters # New pattern which needs to be eliminated
5   D6                        3.3 meters # New pattern which needs to be eliminated
6   D7                        3?3 meters # New pattern which needs to be eliminated
7   M1                    steel|g1_steel
8   M2                             steel
9   M3                          g1_steel

最佳答案

因为您想确保不匹配 3 meters前面有一个数字 + / ,您可以添加 (?<!\d/)初始单词边界后的负向后查找:

df[df['Requirements'].str.contains(fr"\b(?<!\d/)(?:{'|'.join(req_list)})\b")]

输出:

  Name                    Requirements
0   D1  3 meters|2/3 meters|3.5 meters
1   D2                        3 meters
2   D3             3/5 meters|3 meters
4   M1                  steel|g1_steel
5   M2                           steel

请参阅regex demo .

注释

  • req_list包含短语(多字字符串),您可能必须在加入 | 之前按长度按降序对项目进行排序。 OR 运算符,因此您最好使用 fr"\b(?<!\d/)(?:{'|'.join(sorted(req_list, key=len, reverse=True))})\b"作为正则表达式
  • 如果 req_list曾经包含具有特殊字符的项目,您还应该使用 adaptive dynamic word boundaries ,即fr"(?!\B\w)(?<!\d/)(?:{'|'.join(sorted(map(re.escape, req_list), key=len, reverse=True))})(?<!\w\B)" .

关于python - 匹配 DataFrame 列中字符串中的独立单词,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/72651472/

相关文章:

python - Pandas 删除/过滤时间序列数据

python - 选择特定时间之间的所有记录?

Python多处理: How to shutdown a long running process that is a sequence of actions

python - 后台django中的send_mass_mail

javascript - 我需要 javascript 代码中的正则表达式帮助

python - 提取两个点之间的文本,以数字开头

c# - 我在使用 C# 中的多行正则表达式时遇到问题,我该如何解决?

python - Pandas 用特定的阈值计算每一列

Python:用字典键值对中的值替换值

python - 如何分组并获得最频繁的 ngram?