希望执行正则表达式功能以将数据框的列与另一个的第一个字匹配。数据框是从不同来源收集的,因此药物名称相似但不完全匹配。如果忽略大小写并匹配第一个单词,它们确实匹配。
我有两个数据框:一个带有药物名称,另一个带有药物名称及其价格列表。出于示例目的,将水果添加到了药物名称中。
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列的名字并将其与相应的列匹配。
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\-]+)
基于以下stackoverflow问题,我受到启发尝试这种方法:How to merge pandas table by regex。
先谢谢您!我遇到了这个问题的死胡同,无法找到一种方法来使它工作。
答案 0 :(得分:0)
您实际上不需要在第二个数据框中定义正则表达式。 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')
与上面的输出相同。请注意,此版本可能会限制您可以使用的药物数量。如果您有数百种毒品,则可能会遇到问题,因为在这种情况下,正则表达式字符串会变长。但是此版本更清晰,并且在药物名称中还支持空格。 如果您可以设计出一个模式,从而能够正确切出所有药物名称,我建议您使用第一种方法。例如。如果您可以发现一个在药品名称后面的图案,则可以使用它来更容易地剪掉药品名称。