【问题标题】:Map values by comparing 2 columns from different dataframes using partial match in python通过在 python 中使用部分匹配比较来自不同数据帧的 2 列来映射值
【发布时间】:2021-05-20 05:11:05
【问题描述】:

我有 2 个数据框 df1 包含 id_number 和 df2 包含 identity_No。

希望使用条件将最高匹配行值从 Dataframe2 映射到 Dataframe1。想要将 df1 的每一行 (df1['id_number']) 与 df2 的整列 (df2['identity_No']) 进行比较。我也尝试过使用部分匹配,但没有得到输出。

df1

score   id_number       company_name      company_code     match_acc     action_reqd
20      IN2231D           AXN pvt Ltd        IN225                          Yes
45      UK654IN        Aviva Intl Ltd        IN115                          No
65      SL1432H   Ship Incorporations        CZ555                          Yes
35      LK0678G  Oppo Mobiles pvt ltd        PQ795                          Yes
59      NG5678J             Nokia Inc        RS885                          No
20      IN2231D           AXN pvt Ltd        IN215                          Yes

df2

OR_score   identity_No       comp_name        comp_code   
51          UK654IN        Aviva Int.L Ltd       IN515  
25          SL6752J       Ship Inc Traders       CZ555  
79          NG5678K             Nokia Inc        RS005 
20          IN22312           AXN pvt Ltd        IN255
38          LK0665G       Oppo Mobiles ltd       PQ895 

例如: df1.id_number 需要与 df2.identity_No 进行比较,寻找基于 df1['id_number'] 的 row1 匹配将匹配 df2['identity_No'] 的所有行,并且具有最高匹配百分比。 df2['identity_No'] 的第 4 行,并且超过 80%,它会将相应的值从 df2 的第 4 行复制到 df1 的第 1 行。同样适用于 df1 的每一行。

预期输出:

score   id_number       company_name      company_code     match_acc     action_reqd
20      IN22312           AXN pvt Ltd        IN225              90          Yes
51      UK654IN       Aviva Int.L Ltd        IN115              100         No
25      SL1432H   Ship Incorporations        CZ555              30          Yes
38      LK0665G      Oppo Mobiles ltd        PQ795              80          Yes
79      NG5678K             Nokia Inc        RS885              85          No
20      IN22312           AXN pvt Ltd        IN225              90          Yes

我现在已经试过了:

for index, row in df1.iterrows():
    for index2, config2 in df2.iterrows():
        if process.extractOne(row["id_number"], df["identity_No"])[1] >=80:
            df1['id_number'][index] = config2['identity_No']
            df1['company_name'][index] = config2['comp_name']
            df1['company_code'][index] = config2['comp_code']
            df1['score'][index] = config2['OR_Score']

尝试2

for index, row in df1.iterrows():
        for index2, config2 in df2.iterrows():
            if fuzz.partial_ratio(row["id_number"], config2["identity_No"]) >=80:

请推荐

【问题讨论】:

  • @ThePyGuy - 请建议如何解决上述问题。
  • 你试试我的解决方案。我注意到您发布了另一个问题here,另一个用户发布了类似的问题here。
  • @Corralien - 我发布了问题,因为我需要在此处添加一个条件,因为 sal_date 必须介于 from 和 to 之间,请查看问题,不知道另一个用户问题。

标签: python pandas


【解决方案1】:

从我之前的answer开始。

内嵌评论:

import pandas as pd
from fuzzywuzzy import process

# Column mapping between the 2 dataframes
cols1 = ["score", "id_number", "company_name", "company_code"]
cols2 = ["OR_score", "identity_No", "comp_name", "comp_code"]

# Find the single best match above a score in a list of choices.
dfm = pd.DataFrame(df1["id_number"].apply(lambda x: process.extractOne(x, df2["identity_No"]))
                                   .tolist(), columns=["match_comp", "match_acc", "match_idx"])

# Get the indexes of (df1, df2) which satisfy the condition (match_acc> 80)
idx1, idx2 = dfm.loc[dfm["match_acc"] > 80, "match_idx"].reset_index().values.T.tolist()

# Update values from df2 to df1
df1.loc[idx1, cols1] = df2.loc[idx2, cols2].values
df1["match_acc"] = dfm["match_acc"]  # don't forget match_acc column
>>> df1
   score id_number          company_name company_code  match_acc action_reqd
0     20   IN22312           AXN pvt Ltd        IN255         86         Yes
1     51   UK654IN       Aviva Int.L Ltd        IN515        100          No
2     65   SL1432H   Ship Incorporations        CZ555         43         Yes
3     35   LK0678G  Oppo Mobiles pvt ltd        PQ795         71         Yes
4     79   NG5678K             Nokia Inc        RS005         86          No
5     20   IN22312           AXN pvt Ltd        IN255         86         Yes

对您的输入数据进行了测试:

df1 = pd.read_csv(io.StringIO("""score,id_number,company_name,company_code,match_acc,action_reqd
20,IN2231D,AXN pvt Ltd,IN225,,Yes
45,UK654IN,Aviva Intl Ltd,IN115,,No
65,SL1432H,Ship Incorporations,CZ555,,Yes
35,LK0678G,Oppo Mobiles pvt ltd,PQ795,,Yes
59,NG5678J,Nokia Inc,RS885,,No
20,IN2231D,AXN pvt Ltd,IN215,,Yes"""))

df2 = pd.read_csv(io.StringIO("""OR_score,identity_No,comp_name,comp_code
51,UK654IN,Aviva Int.L Ltd,IN515
25,SL6752J,Ship Inc Traders,CZ555
79,NG5678K,Nokia Inc,RS005
20,IN22312,AXN pvt Ltd,IN255
38,LK0665G,Oppo Mobiles ltd,PQ895"""))

【讨论】:

  • 在这一行 df1.loc[idx1, cols1] = df2.loc[idx2, cols2].values 上出现错误“KeyError: '[0] not in index'”
  • 不是我的情况。由于示例数据与提供的格式相同,不明白为什么会出现此错误 KeyError: '[0] not in index, will tr​​y to debug the same
猜你喜欢
  • 2021-11-14
  • 1970-01-01
  • 1970-01-01
  • 2023-03-04
  • 1970-01-01
  • 1970-01-01
  • 2015-10-19
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多