我有一个通过程序运行的文件,用于根据公司名称和地址创建重复的组。如果发现记录具有相同的公司名称和地址,则会为其分配“欺骗组”编号。在第二遍中,我们仅根据电话号码创建欺骗组。这些电话号码欺骗也有一个欺骗组号,但在一个单独的领域。
我现在正在联系这两个欺骗组字段,以创建一个基于公司/地址和/或电话号码的单个组号码。
例如,如果在'123 Main St.'的'ABC公司'在该公司的dupe集团中有10条记录,其中一些记录有一个电话号码,该电话号码也在一个不同公司的骗子组中,在'456 South St'说“ABC公司”我想提供所有记录在两个欺骗组中都有一个id。
原始数据位于单个文件中,其中包含公司/地址欺骗字段和电话欺骗字段。
为此,我创建了两个词典。 一个是PhoneDupe字典,其中'key'是电话欺骗组号,'value'是该电话欺骗组内所有公司欺骗组的列表。
另一个是CompanyDupe dict,其中'key'是公司欺骗组号,'value'是该公司欺骗中所有电话欺诈组的列表。
这是一个小样本:
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 dict中搜索它。当我这样做时,我会发现7125的值为[8719,8715,8710]。然后我需要获取每个值(除了8715,因为我已经搜索过了)并在PhoneDupe dict中查找它们。当我搜索第一个(8719)时,我会得到[7067,7101,7125,7342,8068],当我搜索第二个(8710)时,我会得到[7125,18684](我再次可以忽略7125因为我已经搜索过了)。
这必须一直来回,直到找到所有相关记录。
目标是最终得到应该合并的公司欺骗组列表。
我假设最好的方法是做某种递归函数,在收集所有记录之前一直回到第四位。我还需要传递已经搜索过的id列表。
有没有人知道以这种方式比较两个词典的好方法? 或者,如果有更好的方法可以做到这一点?
到目前为止,我试图将一个phonedupe id与两个dicts一起传递给一个函数,让它获取值然后将其传递回函数但是两个dicts反转然后查看第二个dict for phonedupe ID的。我也传递一个列表来收集已经搜索过的id或记录。最终它将达到无法找到列表中尚未存在的id的点,然后通过所有迭代返回列表以产生具有所有相关记录id的最终列表。
感谢。
修改 对不起,我的问题太长了,我想确保读者能够理解我的目的。
是的,我使用的小样本都是傻瓜。我抓住了我已经知道的所有记录,以确保它抓住了所有记录。我已经测试了我对完整数据的所有信息并且它正在运行。
因为每次我用函数调用函数时我都会反转两个字典,我添加了一个标志来检查字典的长度,所以我知道是否要添加到输出文件中。
当我第一次发布问题时,我没有任何代码可以进入这里,但我能够得到一些工作,所以我现在就发布它。在这种情况下,'pdupe'是电话欺骗,'dupe'是公司欺骗
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 = []
答案 0 :(得分:0)
听起来您希望为c in C
中的每个n
,c
中的p
和PhoneDupes[n]
中的每个co
找到封闭式集CompanyDupes[n]
st } 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])])
你会注意到,实际上每个这样的集合都是相同的,并且似乎包含了样本输入中的每个数字。这就是找到闭集的本质 - 如果没有不相交的子集,那么实际上只有一个闭包。
让我们制作两个不相交的子集,看看会发生什么:
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)
如果您只想从CompanyDupes中获取值:
{{1}}