【问题标题】:Partial String Matching within Groups组内的部分字符串匹配
【发布时间】:2019-04-25 02:05:36
【问题描述】:

我的数据包含一个组(区域),然后还提供了一个名称。我正在尝试合并两个数据框。一帧要小得多,是“映射”数据帧。一个区域内的每个名称都有一行。另一个框架要大得多,是“实例”数据框架。它有许多行,其中包含区域名称的变体。我希望将映射框架中的信息合并到实例框架中,以便每个实例都具有映射框架提供的信息。

我研究了 Fuzzy 包,但没有找到在组(区域列)中实现它的方法,或者如何有效地将它与包含多个字符串的单元格一起使用并尝试基于此进行匹配。

以下是类似数据的示例。合并需要从实例数据框中提取相关信息,以便将其映射到映射数据框。

映射数据框

Area    Name
A   Apple  
A   Orange Strawberry 
A   Blackberry Rasberry 
B   Blackberry 
C   Kiwi  
C   Apple  

实例数据框

Area    Locale
A   Apple Pear Tomato
A   Orange Potato Strawberry Zuccini
A   Blackberry Rasberry 
B   Blackberry Onion
B   Lettuce Blackberry Cucumber 
C   Kiwi Spinach Pineapple
C   Kiwi Potato 
C   Apple Cucumber 
C   Apple Potato 

目标是获得如下所示的框架。

数据框

Area    Locale                                  Name
A   Apple Pear Tomato                   Apple  
A   Orange Potato Strawberry Zuccini    Orange Strawberry 
A   Blackberry Rasberry                 Blackberry Rasberry 
B   Blackberry Onion                    Blackberry 
B   Lettuce Blackberry Cucumber.        Blackberry 
C   Kiwi Spinach Pineapple              Kiwi  
C   Kiwi Potato                         Kiwi  
C   Apple Cucumber                      Apple 
C   Apple Potato                        Apple 

【问题讨论】:

  • 你解决了吗?你最终使用了我的答案吗?如果我能进一步帮助您,请告诉我!

标签: python merge matching fuzzy fuzzywuzzy


【解决方案1】:

使用 fuzz 和 pandas,您可以获得预期的结果。

1) 从收集您的库和数据开始:

import pandas as pd
from fuzzywuzzy import fuzz
mapping = pd.read_excel('Book1.xlsx', sheet_name='mapping')
instance = pd.read_excel('Book1.xlsx', sheet_name='instance')

2) 创建您所在区域的独特价值列表:

unique_area = instance['Area'].drop_duplicates(keep='first').values.tolist()

3) 创建一个空数据框并为每个区域运行以下代码:

fuzzed_data = []
for i in unique_area:
    instanceunique = instance[instance['Area'] == i]
    unique_list = mapping[mapping['Area'] == i]['Name'].drop_duplicates(keep='first').values.tolist()
    instance_score = instanceunique[['Locale']]
    for i in unique_list:
        ratiofuzz = []
        for index, row in instance_score.iterrows():
                ratiofuzz.append(fuzz.ratio(row['Locale'], i))
        instance_score[i] = ratiofuzz
    scores = instance_score.drop(['Locale'], axis=1)
    instance_score['mapping'] = scores.idxmax(axis=1)
    instanceunique = pd.merge(instanceunique
                          , instance_score[['Locale', 'mapping']]
                          , how='left'
                          , on=['Locale'])
    fuzzed_data.append(instanceunique)

4) 连接“模糊”数据:

fuzzed_data = pd.concat(fuzzed_data, axis=0)

就是这样! 如果您需要更多帮助,请告诉我。 BR

【讨论】:

  • 感谢您的回复。运行代码后出现错误“值的长度与索引的长度不匹配”
  • 我已经尝试过了,它在你上面给出的例子中对我有用。也许您没有使用相同的数据?另外,请注意最后一部分(pd.concat)在循环之外。
猜你喜欢
  • 1970-01-01
  • 2012-06-15
  • 2019-10-18
  • 2015-10-30
  • 2017-07-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多