用相同的字符串替换列中的类似字符串

时间:2017-11-26 19:47:56

标签: python python-3.x pandas

我有一个Pandas数据框,用于收集进行交易的供应商的名称。由于这些数据是从银行对账单中自动收集的,因此许多供应商都很相似......但不完全相同。总之,我想用一个名称替换供应商名称的不同排列。

我想我可以找到一种方法(见下文),但我是初学者,这对我来说似乎是一个复杂的问题。我真的很想知道更有经验的编码员会如何接近它。

我有一个这样的数据帧(在现实生活中,它大约有20列,最多约50行):

cv

我想找到类似的条目,并用这些条目的第一个实例替换它们,所以我最终得到了这个:

     Groceries            Car                Luxuries
0    Sainsburys           Texaco wst453      Amazon
1    Sainsburys bur       Texaco east        Firebox Ltd
2    Sainsbury's east     Shell wstl         Sony
3    Tesco                Shell p/stn        Sony ent nrk
4    Tescos ref 657       Texac              Amazon EU
5    Tesco 45783          Moto               Amazon marketplace

我的解决方案可能远非最佳。我想按字母顺序排序,然后按位进行,并使用difflib中的SequenceMatcher来比较每对供应商。如果相似度超过一定百分比(我希望在我开心之前使用此值),那么两个供应商将被假定为相同。我担心我可能会使用大锤来破解螺母,或者可能需要很长时间(我并不痴迷于性能,但同样我也不想等待数小时才能获得结果)。

真的很想听听别人对这个问题的看法!

1 个答案:

答案 0 :(得分:0)

一开始,问题似乎并不复杂,但确实如此。我不喜欢我的代码,必须有更好的方法。但是我的代码正在运行。

我使用名为fuzzywuzzy的字符串相似性包来决定必须替换哪个字符串。该软件包使用Levenshtein相似性,我使用%90作为阈值。此外,任何字符串的第一个单词用作比较字符串。这是我的代码:

import pandas
from fuzzywuzzy import fuzz

# Replaces %90 and more similar strings  
def func(input_list):
    for count, item in enumerate(input_list):
        rest_of_input_list = input_list[:count] + input_list[count + 1:]
        new_list = []
        for other_item in rest_of_input_list:
            similarity = fuzz.ratio(item, other_item)
            if similarity >= 90:
                new_list.append(item)
            else:
                new_list.append(other_item)
        input_list = new_list[:count] + [item] + new_list[count :]

    return input_list

df = pandas.read_csv('input.txt') # Read data from csv
result = []
for column in list(df):
    column_values = list(df[column])
    first_words = [x[:x.index(" ")] if " " in x else x for x in column_values]
    result.append(func(first_words))

new_df = pandas.DataFrame(result).transpose() 
new_df.columns = list(df)

print(new_df)

输出:

     Groceries    Car Luxuries
0  Sainsbury's  Texac   Amazon
1  Sainsbury's  Texac  Firebox
2  Sainsbury's  Shell     Sony
3        Tesco  Shell     Sony
4        Tesco  Texac   Amazon
5        Tesco   Moto   Amazon

我想,func()函数可以更好地编码,但这是我首先想到的。