【问题标题】:FuzzyWuzzy - Loop through list, match accepted values, and return a dataframeFuzzyWuzzy - 遍历列表,匹配接受的值,并返回一个数据帧
【发布时间】:2017-05-16 01:21:12
【问题描述】:

目标

  • 给定一个 excel 文件(全是错别字),使用 FuzzyWuzzy 比较和 将拼写错误与accepted 列表相匹配。
  • 用最接近的 accepted 匹配更正填错的 Excel 文件。

方法

  1. 使用 pandas 导入 Excel 文件
  2. 将原始的、拼写错误的 Excel 文件推送到数据框中
  3. 创建一个accepted 数据框
  4. 使用FuzzyWuzzy 比较错字数据框与accepted 数据框
  5. 返回原始拼写、接受的拼写和匹配分数
  6. 将相关的、可接受的拼写附加到所有拼写的原始 Excel 文件/行中

代码

#Load Excel File into dataframe
xl = pd.read_excel(open("/../data/expenses.xlsx",'rb'))

#Let's clarify how many similar categories exist... 
q = """
    SELECT DISTINCT Expense 
    FROM xl
    ORDER BY Expense ASC

"""

expenses = sqldf(q)
print(expenses)

#Let's add some acceptable categories and use fuzzywuzzy to match
accepted = ['Severance', 'Legal Fees', 'Import & Export Fees', 'I.T. Fees', 'Board Fees', 'Acquisition Fees']

#select from the list of accepted values and return the closest match
process.extractOne("Company Acquired",accepted,scorer=fuzz.token_set_ratio)

('购置费', 38) 分数不高,但足够高,可以返回预期的输出

!!!!!问题!!!!!

#Time to loop through all the expenses and use FuzzyWuzzy to generate and return the closest matches.
def correct_expense(expense):
    for expense in expenses:
        return expense, process.extractOne(expense,accepted,scorer = fuzz.token_set_ratio)

correct_expense(expenses)

('费用', ('法律费用', 47))

问题

  1. 如您所见,process.extractOne 在逐个测试时运行正确。但是,在循环中运行时,返回值是意外的。我相信我可能会抓住第一列或最后一列,但即使是这样,我也希望“董事费”或“收购”会弹出(参见原始 excel 文件)。

【问题讨论】:

  • correct_expense()中至少有两个问题:你在循环内部返回,参数名称与循环变量相同。

标签: python pandas fuzzywuzzy


【解决方案1】:

这称为地名词典重复数据删除。
您通过将杂乱的数据与规范数据(即公报)进行匹配来执行重复数据删除。

pandas-dedupe 可以做到这一点。
示例:

import pandas as pd
import pandas_dedupe

clean_data = pd.DataFrame({'street': ['Onslow square', 'Sydney Mews', 'Summer Place', 'Bury Walk', 'sydney mews']})
messy_data = pd.DataFrame({'street_name':['Onslow sq', 'Sidney Mews', 'Summer pl', 'Onslow square', 'Bury walk', 'onslow sq', 'Bury Wall'],
                           'city' : ['London', 'London', 'London', 'London', 'London', 'London', 'London']})

dd = pandas_dedupe.gazetteer_dataframe(
    clean_data, 
    messy_data, 
    field_properties = 'street_name', 
    canonicalize=True,
    )

在此过程中,pandas-dedupe 会要求您将少数示例标记为重复或不同的记录。然后,图书馆将使用这些知识来查找潜在的重复条目,将它们与干净的数据进行匹配并返回所有相关信息,包括对结果的置信度。

【讨论】:

    【解决方案2】:

    我过去这样做的方式是只使用 Python 中 difflib 模块中的 get_closest_matches 函数。然后,您可以创建一个函数来获取最接近的匹配并将其应用于Expense 列。

    def correct_expense(row):
        accepted = ['Severance', 'Legal Fees', 'Import & Export Fees', 'I.T. Fees', 'Board Fees', 'Acquisition Fees']
        match = get_close_matches(row, accepted, n=1, cutoff=0.3)
        return match[0] if match else ''
    
    df['Expense_match'] = df['Expense'].apply(correct_expense)
    

    这是原始的 Expense 列,其值与 accepted 列表匹配:

    您可能需要微调accepted 列表和get_closest_matchescutoff 值(我发现0.3 对您的示例数据非常有效)。

    对结果满意后,您可以更改函数以覆盖Expense 列并使用pandas DataFrame 方法to_excel 保存到Excel。

    【讨论】:

      猜你喜欢
      • 2023-01-19
      • 1970-01-01
      • 2011-10-12
      • 2020-06-18
      • 1970-01-01
      • 1970-01-01
      • 2021-12-11
      • 2019-02-15
      • 1970-01-01
      相关资源
      最近更新 更多