希望执行正则表达式函数来将一列数据帧与另一列数据帧的第一个单词进行匹配。这些数据帧来自不同的来源,因此药物的名称相似,但并不完全匹配。如果忽略大小写并匹配第一个单词,它们就会匹配。
我有两个数据帧:一个是药品名称,另一个是药品名称和各自价格的列表。出于举例的目的,水果被添加到药品名称中。
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,如下所示。希望使用药物列的名字,并将其与相应的列进行匹配。
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。
提前谢谢你!我遇到了这个问题的死胡同,不能想出一种方法让它工作。
发布于 2019-08-13 01:50:24
您实际上不需要在第二个dataframe中定义正则表达式。顺便说一句,ALollz是对的。你可以很容易地拆分字符串,但我猜你需要这样做的目的是更复杂的,而且你可能有包含空格的药物名称。
具有通用正则表达式的简单版本
如果您可以设法定义一个与所有药物名称匹配的通用正则表达式,则可以使用以下代码:
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')只需将后面的表达式替换为所需的正则表达式。输出将为:
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带有生成的正则表达式的版本
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')此输出与上面的输出相同。请注意,此版本可能会限制您可以使用的药物数量。如果有数百种药物,它可能会遇到问题,因为在这种情况下,正则表达式字符串会变得很长。但这个版本更清晰,而且还支持药品名称中的空格。如果你能设计出一种模式,能够正确地切出所有的药物名称,我绝对推荐使用第一种方法。例如,如果你能识别出药物名称后面的模式,你就可以用它来更容易地去掉药物名称。
https://stackoverflow.com/questions/57464972
复制相似问题