按具有相似字符串的列合并两个 csv 文件
Merge two csv-files by columns with similars strings
我开始使用pandas,我遇到了一个我不知道如何解决的问题。
我有两个数据框。
第一个包含汽车信息,包括车型(第 DESCR_MARCA_VEICULO 列)
df1
col1 col2 DESCR_MARCA_VEICULO
.... .... 'GM/CELTA 5 PORTAS SUPER'
.... .... 'VW/VOYAGE LS'
.... .... 'VW/GOL LS'
.... .... 'I/AUDI A4 2.0T FSI'
.... .... 'FIAT/UNO CS IE'
第二个包含一个双列 de-para,其中包含汽车型号和与该型号关联的唯一 ID,如下所示:
df2
ID DESCR_MARCA_VEICULO
1 'GM - CELTA 5'
2 'VW - VOYAGE LS'
3 'VW - GOL LS'
4 'ACURA - INTEGRA GS 1.8'
5 'AUDI - 80 S2 AVANT'
而且它不一定遵循将“/”替换为“-”之类的模式。
但是,我在 DF1 中有超过 5000 种不同的车型(这让我无法逐个查看),我需要结合 DF1 和 DF2 将 ID 列带到 DF1(这将是一个合并).但是,当我合并 dfs 时,由于这些字符串差异,没有匹配项。
有什么方法可以根据 DESCR_MARCA_VEICULO 列中字符串之间的相似性来合并这些 dfs 吗?
谢谢:)
我建议您使用 fuzzywuzzy 包研究模糊匹配
一个技巧是删除字符串中除字母和数字之外的所有字符
df1['var'] = df1['DESCR_MARCA_VEICULO'].str.replace('[^A-Za-z0-9]','')
df2['var'] = df2['DESCR_MARCA_VEICULO'].str.replace('[^A-Za-z0-9]','')
m = pd.merge(df1,df2,on='var').drop('var',axis=1)
print(m)
col1 col2 DESCR_MARCA_VEICULO_x matches ID DESCR_MARCA_VEICULO_y
0 .... .... VW/VOYAGE LS VWVOYAGELS 2 VW - VOYAGE LS
1 .... .... VW/GOL LS VWGOLLS 3 VW - GOL LS
我们怎么会缺少几个需要匹配的键:让我们使用 Erfan 从这个 post
中得到的答案
from fuzzywuzzy import fuzz
from fuzzywuzzy import process
def fuzzy_merge(df_1, df_2, key1, key2, threshold=90, limit=2):
"""
df_1 is the left table to join
df_2 is the right table to join
key1 is the key column of the left table
key2 is the key column of the right table
threshold is how close the matches should be to return a match, based on Levenshtein distance
limit is the amount of matches that will get returned, these are sorted high to low
"""
s = df_2[key2].tolist()
m = df_1[key1].apply(lambda x: process.extract(x, s, limit=limit))
df_1['matches'] = m
m2 = df_1['matches'].apply(lambda x: ', '.join([i[0] for i in x if i[1] >= threshold]))
df_1['matches'] = m2
return df_1
print(fuzzy_merge(df1, df2, 'var', 'var', threshold=80))
col1 col2 DESCR_MARCA_VEICULO var matches
0 .... .... GM/CELTA 5 PORTAS SUPER GMCELTA5PORTASSUPER GMCELTA5
1 .... .... VW/VOYAGE LS VWVOYAGELS VWVOYAGELS
2 .... .... VW/GOL LS VWGOLLS VWGOLLS
3 .... .... I/AUDI A4 2.0T FSI IAUDIA420TFSI
4 .... .... FIAT/UNO CS IE FIATUNOCSIE
我开始使用pandas,我遇到了一个我不知道如何解决的问题。
我有两个数据框。
第一个包含汽车信息,包括车型(第 DESCR_MARCA_VEICULO 列)
df1
col1 col2 DESCR_MARCA_VEICULO
.... .... 'GM/CELTA 5 PORTAS SUPER'
.... .... 'VW/VOYAGE LS'
.... .... 'VW/GOL LS'
.... .... 'I/AUDI A4 2.0T FSI'
.... .... 'FIAT/UNO CS IE'
第二个包含一个双列 de-para,其中包含汽车型号和与该型号关联的唯一 ID,如下所示:
df2
ID DESCR_MARCA_VEICULO
1 'GM - CELTA 5'
2 'VW - VOYAGE LS'
3 'VW - GOL LS'
4 'ACURA - INTEGRA GS 1.8'
5 'AUDI - 80 S2 AVANT'
而且它不一定遵循将“/”替换为“-”之类的模式。
但是,我在 DF1 中有超过 5000 种不同的车型(这让我无法逐个查看),我需要结合 DF1 和 DF2 将 ID 列带到 DF1(这将是一个合并).但是,当我合并 dfs 时,由于这些字符串差异,没有匹配项。
有什么方法可以根据 DESCR_MARCA_VEICULO 列中字符串之间的相似性来合并这些 dfs 吗?
谢谢:)
我建议您使用 fuzzywuzzy 包研究模糊匹配
一个技巧是删除字符串中除字母和数字之外的所有字符
df1['var'] = df1['DESCR_MARCA_VEICULO'].str.replace('[^A-Za-z0-9]','')
df2['var'] = df2['DESCR_MARCA_VEICULO'].str.replace('[^A-Za-z0-9]','')
m = pd.merge(df1,df2,on='var').drop('var',axis=1)
print(m)
col1 col2 DESCR_MARCA_VEICULO_x matches ID DESCR_MARCA_VEICULO_y
0 .... .... VW/VOYAGE LS VWVOYAGELS 2 VW - VOYAGE LS
1 .... .... VW/GOL LS VWGOLLS 3 VW - GOL LS
我们怎么会缺少几个需要匹配的键:让我们使用 Erfan 从这个 post
中得到的答案from fuzzywuzzy import fuzz
from fuzzywuzzy import process
def fuzzy_merge(df_1, df_2, key1, key2, threshold=90, limit=2):
"""
df_1 is the left table to join
df_2 is the right table to join
key1 is the key column of the left table
key2 is the key column of the right table
threshold is how close the matches should be to return a match, based on Levenshtein distance
limit is the amount of matches that will get returned, these are sorted high to low
"""
s = df_2[key2].tolist()
m = df_1[key1].apply(lambda x: process.extract(x, s, limit=limit))
df_1['matches'] = m
m2 = df_1['matches'].apply(lambda x: ', '.join([i[0] for i in x if i[1] >= threshold]))
df_1['matches'] = m2
return df_1
print(fuzzy_merge(df1, df2, 'var', 'var', threshold=80))
col1 col2 DESCR_MARCA_VEICULO var matches
0 .... .... GM/CELTA 5 PORTAS SUPER GMCELTA5PORTASSUPER GMCELTA5
1 .... .... VW/VOYAGE LS VWVOYAGELS VWVOYAGELS
2 .... .... VW/GOL LS VWGOLLS VWGOLLS
3 .... .... I/AUDI A4 2.0T FSI IAUDIA420TFSI
4 .... .... FIAT/UNO CS IE FIATUNOCSIE