Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/python-2.7/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 如果_eq _函数使用编辑距离确定相等,那么_hash _函数的最佳实现是什么?_Python_Python 2.7_Hash_Set_Set Intersection - Fatal编程技术网

Python 如果_eq _函数使用编辑距离确定相等,那么_hash _函数的最佳实现是什么?

Python 如果_eq _函数使用编辑距离确定相等,那么_hash _函数的最佳实现是什么?,python,python-2.7,hash,set,set-intersection,Python,Python 2.7,Hash,Set,Set Intersection,我有一个奇怪的要求,我需要从两个不同的非常大的列表中找到常见的“客户”。两个列表中的每个条目都是一个Customer对象,其中包含客户的名字和姓氏及其地址(按地址行细分,如address_line1、address_line2等)。问题在于,两个列表中的数据都可能不完整,例如,对于第一个列表中的一个记录,客户的名字可能缺失,而在第二个列表中,对于同一客户,其地址(第2行和第3行)可能缺失。我需要做的是找到两个列表中的客户。需要注意的一点是,列表可能很大。要记住的另一点是,名称和地址在语义上可能相

我有一个奇怪的要求,我需要从两个不同的非常大的列表中找到常见的“客户”。两个列表中的每个条目都是一个Customer对象,其中包含客户的名字和姓氏及其地址(按地址行细分,如address_line1、address_line2等)。问题在于,两个列表中的数据都可能不完整,例如,对于第一个列表中的一个记录,客户的名字可能缺失,而在第二个列表中,对于同一客户,其地址(第2行和第3行)可能缺失。我需要做的是找到两个列表中的客户。需要注意的一点是,列表可能很大。要记住的另一点是,名称和地址在语义上可能相同,但在进行精确的字符串匹配时可能不会返回结果。例如,在第一个列表中,第一个列表中的客户地址可以是
B-502 ABC Street
格式,而第二个列表中相同客户的地址可以是
B 502 ABC Street
格式。我使用“编辑距离”的原因是为了说明列表中的用户输入错误,并处理两个列表中存在的数据中的某些其他细微差异

我所做的是在Customer类中实现eq函数,如下所示

import re
import editdistance # Using this: https://pypi.python.org/pypi/editdistance

class Customer:
    def __init__(self, fname, lname, address1, address2, address3, city):
        # Removing special characters from all arguments and converting them to lower case
        self.fname = re.sub("[^a-zA-Z0-9]", "", fname.lower())
        self.lname = re.sub("[^a-zA-Z0-9]", "", lname.lower())
        self.address1 = re.sub("[^a-zA-Z0-9]", "", address1.lower())
        self.address2 = re.sub("[^a-zA-Z0-9]", "", address2.lower())
        self.address3 = re.sub("[^a-zA-Z0-9]", "", address3.lower())
        self.city = re.sub("[^a-zA-Z0-9]", "", city.lower())

    def __eq__(self, other):
        if self.lname == "" or self.lname != other.lname:
            return False

        t = 0

        if self.fname != "" and other.fname != "" and self.fname[0] == other.fname[0]:
            t += 1

        if editdistance.eval(self.fname, other.fname) <= 2:
            t += 3

        if editdistance.eval(self.address1, other.address1) <= 3:
            t += 1

        if editdistance.eval(self.address2, other.address2) <= 3:
            t += 1

        if editdistance.eval(self.address3, other.address3) <= 3:
            t += 1

        if editdistance.eval(self.city, other.city) <= 2:
            t += 1

        if t >= 4:
            return True

        return False

    def __hash__():
        # TODO:  Have a robust implementation of a hash function here. If two objects are "equal", their hashes should be the same
重新导入
使用以下方法导入editdistance#:https://pypi.python.org/pypi/editdistance
类别客户:
定义初始化(self,fname,lname,address1,address2,address3,city):
#从所有参数中删除特殊字符并将其转换为小写
self.fname=re.sub(“[^a-zA-Z0-9]”,“”,fname.lower()
self.lname=re.sub(“[^a-zA-Z0-9]”,“”,lname.lower()
self.address1=re.sub(“[^a-zA-Z0-9]”,“”,address1.lower()
self.address2=re.sub(“[^a-zA-Z0-9]”,“”,address2.lower()
self.address3=re.sub(“[^a-zA-Z0-9]”,“”,address3.lower()
self.city=re.sub(“[^a-zA-Z0-9]”,“”,city.lower()
定义(自身、其他):
如果self.lname==“”或self.lname!=other.lname:
返回错误
t=0
如果self.fname!=“”和其他。fname!=“”和self.fname[0]==其他.fname[0]:
t+=1

如果editdistance.eval(self.fname,other.fname)您唯一的选择是规范化数据。如果您需要比较相等性,并且可能有不同的格式,则解决方案是标准化。转换所有内容,使其在两个列表中的格式相同

我在西班牙为地址的标准化算法工作了几个月。对于同一个地址,不同用户输入的组合是无止境的(我正在处理一个700万行的数据库)。使用该距离函数可能不够精确,除非您确切知道同一地址的不同可能格式以及函数返回的这些差异的距离

第一个关键问题是,你能承受的错误百分比是多少?因为有了用户输入和大数据,你总是会有一些

下一步是测量使用该距离算法(或任何其他算法)得到的误差百分比。仔细选择样本数据,以便百分比不会随完整数据而变化

如果这个百分比适合你,你就使用那个算法,如果不适合,就找其他算法并测量它们