我有一个数据框,例如:
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/