0

我有一个通过程序运行的文件,用于根据公司名称和地址创建重复组。如果发现记录具有相同的公司名称和地址,则会为其分配一个“重复组”编号。在第二遍中,我们仅根据电话号码创建欺骗组。这些电话号码被骗者也被赋予了一个被骗者组号码,但在一个单独的字段中。

我现在正在将这两个欺骗组字段结合起来,以创建一个基于公司/地址和/或电话号码的单一欺骗组号码。

例如,如果 '123 Main St.' 的 'ABC company' 在公司欺骗组中有 10 条记录,其中一些记录有一个电话号码,并且该电话号码也在另一家公司的欺骗组中,例如 'ABC company' at '456 South St' 我想提供所有记录在两个骗子组中都有一个 id。

原始数据位于单个文件中,其中一个字段用于公司/地址欺骗,另一个字段用于电话欺骗。

为此,我创建了两个字典。一个是PhoneDupe dict,其中“key”是电话欺骗组号码,“value”是该电话欺骗组内所有公司欺骗组的列表。

另一个是 CompanyDupe 字典,其中“键”是公司欺骗组号码,“值”是该公司欺骗中所有电话欺骗组的列表。

这是一个小样本:

PhoneDupes = {8715: [7125], 8710: [7125, 18684], 8719: [7067, 7101, 7125, 7342, 8068]}

CompanyDupes = {8068: [8719], 7342: [8719], 7125: [8719, 8715, 8710], 7067: [8719], 18684: [8710], 7101: [8719]}

在此示例中,PhoneDupes 中的第一项是 #8715,其值为 7125。然后我需要获取该值并在 CompanyDupes 字典中搜索它。当我这样做时,我会发现 7125 的值是 [8719, 8715, 8710]。然后我需要获取这些值中的每一个(8715 除外,因为我已经搜索过了)并在 PhoneDupe 字典中查找它们。当我搜索第一个 (8719) 时,我会得到 [7067, 7101, 7125, 7342, 8068],当我搜索第二个 (8710) 时,我会得到 [7125, 18684] (我可以再次忽略 7125,因为我已经搜索过了)。

这必须不断来回,直到我找到所有相关的记录。

目标是最终列出应合并的公司欺骗组列表。

我假设做到这一点的最好方法是某种递归函数,它不断地往回走,直到收集到所有记录。我还需要传递一个已经搜索过的 id 列表。

有谁知道以这种方式比较两个字典的好方法?或者是否有更好的方法来做到这一点?

到目前为止,我正在尝试将一个 phonedupe id 与两个 dicts 一起传递给一个函数,让它获取值,然后将其传递回函数,但是两个 dicts 颠倒,然后查看第二个 dict 的 phonedupe id。我还传递了一个列表来收集已搜索的 ID 或记录。最终它将到达无法找到列表中尚未存在的任何 id 的程度,然后通过所有迭代返回列表以生成具有所有关联记录 id 的最终列表。

谢谢。

编辑: 对不起,我的问题太长了,我想确保读者能够理解我想要做什么。

是的,我使用的小样本都是骗子。我只是抓住了所有我已经知道是骗子的记录,以确保它抓住了所有记录。我已经测试了我对完整数据的了解,并且它正在工作。

因为每次我从函数中调用函数时,我都在反转两个字典,我添加了检查字典长度的标志,所以我知道是否添加到输出文件中。

当我第一次发布问题时,我没有任何代码可以在这里输入,但是我能够得到一些工作,所以我现在就发布它。在这种情况下,“pdupe”是电话骗子,“骗子”是公司骗子

def test_rollup(id,comb_list,dict1,dict2,flag):
for dupe in dict1[id]:
    if dupe not in comb_list and comb_list != None:
        if flag == len(dict1):
            comb_list.append(dupe)
            test_rollup(dupe,comb_list,dict2,dict1,flag)
        else:
            test_rollup(dupe,comb_list,dict2,dict1,flag)
return comb_list

for id in pdupe:
    test_rollup(id,comb_list,pdupe,dupe,len(pdupe))
    if sorted(comb_list) not in master_list:
        master_list.append(sorted(comb_list))
    comb_list = []
4

1 回答 1

0

听起来您想为 each in 、 every in和 every in is in找到闭集c in Cst 。ncpPhoneDupes[n]coCompanyDupes[n]c

作为第一遍,让我们构建一些我们知道相关联的数字集:

PhoneDupes = {8715: [7125], 8710: [7125, 18684], 8719: [7067, 7101, 7125, 7342, 8068]}

CompanyDupes = {8068: [8719], 7342: [8719], 7125: [8719, 8715, 8710], 7067: [8719], 18684: [8710], 7101: [8719]}
[set([n]+PhoneDupes.get(n, [])+CompanyDupes.get(n, [])) for n in PhoneDupes]

我们应该如何处理这些?可能是完全相同的事情:

import itertools
def closure(inset, acc = set()):
    new = set(itertools.chain.from_iterable(itertools.chain(PhoneDupes.get(n, []),CompanyDupes.get(n, []))  for n in inset))
    really_new = (new - inset) - acc
    if not really_new: return inset|acc
    else: return closure(really_new, inset|acc)

closed_sets = [closure(set([n]+PhoneDupes.get(n, [])+CompanyDupes.get(n, []))) for n in PhoneDupes]
#=> [set([8068, 8710, 8715, 7342, 8719, 7125, 7067, 18684, 7101]), set([8068, 8710, 8715, 7342, 8719, 7125, 7067, 18684, 7101]), set([8068, 8710, 8715, 7342, 8719, 7125, 7067, 8684, 7101])]

closed_sets ==  [closure(s) for s in closed_sets]
#=> True

您会注意到,实际上每个这样的集合都是相同的,并且似乎包括来自您的样本输入的每个数量。这就是寻找闭集的本质——如果没有不相交的子集,那么实际上只有一个闭包。

让我们制造两个不相交的子集,看看会发生什么:

PhoneDupes2  = {k+1:[n+1 for n in v] for k,v in PhoneDupes.iteritems()}
CompanyDupes2  = {k+1:[n+1 for n in v] for k,v in CompanyDupes.iteritems()}
PhoneDupes.update(PhoneDupes2)
CompanyDupes.update(CompanyDupes2)
closed_sets = [closure(set([n]+PhoneDupes.get(n, [])+CompanyDupes.get(n, []))) for n in PhoneDupes]
#deduplicate closed_sets
frozenset(frozenset(s) for s in closed_sets)
#=> frozenset([frozenset([8068, 8710, 8715, 7342, 8719, 7125, 7067, 18684, 7101]), frozenset([8069, 8711, 8716, 7343, 8720, 7126, 7068, 18685, 7102])])

如果您只想从 CompanyDupes 获取值:

def closure_co(inset, acc = set(), co_acc=set()):
    newphone = set(itertools.chain.from_iterable(PhoneDupes.get(n, []) for n in inset))
    newco = set(itertools.chain.from_iterable(CompanyDupes.get(n, [])  for n in inset))
    really_new = ((newphone|newco) - inset) - acc
    if not really_new: return co_acc
    else: return closure_co(really_new, inset|acc, co_acc|newco)
于 2013-07-25T23:51:21.857 回答