首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用正则表达式匹配dataframe中的列

使用正则表达式匹配dataframe中的列
EN

Stack Overflow用户
提问于 2019-08-13 00:32:54
回答 1查看 320关注 0票数 0

希望执行正则表达式函数来将一列数据帧与另一列数据帧的第一个单词进行匹配。这些数据帧来自不同的来源,因此药物的名称相似,但并不完全匹配。如果忽略大小写并匹配第一个单词,它们就会匹配。

我有两个数据帧:一个是药品名称,另一个是药品名称和各自价格的列表。出于举例的目的,水果被添加到药品名称中。

代码语言:javascript
复制
Dataframe A  
      drug
0   drug1 apple
1   drug2 orange
2   drug3 lemon
3   drug4 peach

Dataframe B
   drugB    price   Regex
0  DRUG2     2  ^([\w\-]+)
1  DRUG4     4  ^([\w\-]+)
2  DRUG3     3  ^([\w\-]+)
3  DRUG1     1  ^([\w\-]+)

我希望使用Regex列将数据帧A附加到B,如下所示。希望使用药物列的名字,并将其与相应的列进行匹配。

代码语言:javascript
复制
       drug         drugB   price   Regex
0   drug1 apple     DRUG1     1  ^([\w\-]+)
1   drug2 orange    DRUG2     2  ^([\w\-]+)
2   drug3 lemon     DRUG3     3  ^([\w\-]+)
3   drug4 peach     DRUG4     4  ^([\w\-]+)

我是基于下面的堆栈溢出问题来尝试这种方式的:How to merge pandas table by regex

提前谢谢你!我遇到了这个问题的死胡同,不能想出一种方法让它工作。

EN

回答 1

Stack Overflow用户

发布于 2019-08-13 01:50:24

您实际上不需要在第二个dataframe中定义正则表达式。顺便说一句,ALollz是对的。你可以很容易地拆分字符串,但我猜你需要这样做的目的是更复杂的,而且你可能有包含空格的药物名称。

具有通用正则表达式的简单版本

如果您可以设法定义一个与所有药物名称匹配的通用正则表达式,则可以使用以下代码:

代码语言:javascript
复制
df_A['drugA']= df_A['drug'].str.extract('^\s*(?P<drugA>[\w\-]*)')['drugA'].str.upper()
df_A.merge(df_B[['drugB', 'price']], left_on='drugA', right_on='drugB', how='left')

只需将后面的表达式替换为所需的正则表达式。输出将为:

代码语言:javascript
复制
           drug  drugA  drugB  price
0   drug1 apple  DRUG1  DRUG1      1
1  drug2 orange  DRUG2  DRUG2      2
2   drug3 lemon  DRUG3  DRUG3      3
3   drug4 peach  DRUG4  DRUG4      4

带有生成的正则表达式的版本

代码语言:javascript
复制
drug_list= df_B['drugB'].to_list()
# sort the drug names by length descending
# to make sure we get the longest match
# --> relevant only if a drug name is included
#     fully in another name
#     Like "Aspirin" & "Aspirin plus C"
drug_list.sort(key=lambda drug: len(drug), reverse=True)

drug_pattern= '^\s*(?P<drugA>{drug_list})'.format(drug_list='|'.join(drug_list))

df_A['drugA']= df_A['drug'].str.extract(drug_pattern, re.I)['drugA'].str.upper()

df_A.merge(df_B[['drugB', 'price']], left_on='drugA', right_on='drugB', how='left')

此输出与上面的输出相同。请注意,此版本可能会限制您可以使用的药物数量。如果有数百种药物,它可能会遇到问题,因为在这种情况下,正则表达式字符串会变得很长。但这个版本更清晰,而且还支持药品名称中的空格。如果你能设计出一种模式,能够正确地切出所有的药物名称,我绝对推荐使用第一种方法。例如,如果你能识别出药物名称后面的模式,你就可以用它来更容易地去掉药物名称。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/57464972

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档