首页 > 解决方案 > 按具有相似字符串的列合并两个 csv 文件

问题描述

我开始使用 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'

第二个包含一个包含汽车模型和与该模型关联的唯一 ID 的双列 de-para,如下所示:

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?

谢谢 :)

标签: pythonpandasdataframemergesimilarity

解决方案


我建议您使用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 在这篇文章中的回答

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   

推荐阅读