[英]Regex - Match substring with Strings
我有 2 个数据框,我想要创建一个匹配的 ID 列表。 有了这些信息,我可以稍后执行合并(合并不是我的问题的一部分,我只想找出如何正确匹配行)。
DF1
ID |
---|
123 |
123B |
234 |
234B |
456 |
456B |
asfdh5 |
45gh |
DF2
ID |
---|
123456 |
123B456 |
BBBER4 |
234567YT |
B9234BAA |
456XXA32 |
999GHF |
pp9985 |
88AVKVBD |
期望的结果- 我想得到一个匹配的字符串列表
火柴 | |
---|---|
0 | 123 |
1 | 123B |
2 | 钠 |
3 | 234 |
4 | 234B |
5 | 456 |
6 | 钠 |
7 | 钠 |
8 | 钠 |
我正在使用的当前代码如下
df2['ID'].str.extract(fr"({'|'.join(df1['ID'].values)})", expand=False)
问题是此代码与 DF1 中的 ID 不完全匹配,如果您在所需结果上方看到索引 2,则结果为123B ,但我只得到 123。
以下是我使用当前代码得到的结果。
火柴 | |
---|---|
0 | 123 |
1 | 123 |
2 | 钠 |
3 | 234 |
4 | 234 |
5 | 456 |
6 | 钠 |
7 | 钠 |
8 | 钠 |
任何帮助将非常感激。 谢谢你,西安
这种行为是预期的,因为“对于系列中的每个主题字符串,从正则表达式 pat 的第一个匹配中提取组。” ( https://pandas.pydata.org/docs/reference/api/pandas.Series.str.extract.html )。 所以你得到 '123' 而不是 '123B' 因为 '123' 是df1
系列中的第一个值,因此是第一个匹配项。
您的问题是它在查找匹配项并返回第一个匹配项时从 DF1 的顶部进行检查。 如果您按列中字符串的长度对 dataframe 进行排序,则会返回最长的匹配项。
这应该可以解决您的问题:
# Sort by length of string
new_index = df1.ID.str.len().sort_values().index
df1 = df1.reindex(index = new_index[::-1]).reset_index(drop=True)
# Match strings
df2['ID'].str.extract(fr"({'|'.join(df1['ID'].values)})", expand=False)
您需要做的就是使用sorted(df1['ID'].values, key=len, reverse=True)
按长度对df1['ID']
值进行降序排序:
>>> df2['ID'].str.extract(fr"({'|'.join(sorted(df1['ID'].values, key=len, reverse=True))})", expand=False)
0 123
1 123B
2 NaN
3 234
4 234B
5 456
6 NaN
7 NaN
8 NaN
Name: ID, dtype: object
你需要这个,因为 NFA 正则表达式引擎(Python 的re
is)中更长的替代方案总是“获胜”,并且同一组中的所有其他替代方案甚至都没有被正则表达式引擎尝试。 请参阅记住 Regex 引擎是 Eager 。 例如。 你在你的正则表达式中 hd 123|123B
,所以123
匹配123B456
中的123
并返回该匹配,没有尝试123B
替代,依此类推。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.