在python中查找大量列表的交集
我有一个文件,每行包含空格分隔的数字。每行对应一个数字列表。 现在大约有300000行这样的代码,每行平均包含100个数字。 我想找到所有这些列表的相互交集,即第一个列表与所有其他列表相交,然后第二个列表与所有其他列表相交,依此类推。 我正在使用在python中查找大量列表的交集,python,processing-efficiency,computation,Python,Processing Efficiency,Computation,我有一个文件,每行包含空格分隔的数字。每行对应一个数字列表。 现在大约有300000行这样的代码,每行平均包含100个数字。 我想找到所有这些列表的相互交集,即第一个列表与所有其他列表相交,然后第二个列表与所有其他列表相交,依此类推。 我正在使用 set(a) & set(b) 其中a和b是在双循环中迭代得到的列表。 但这需要花费太多的时间。例如:对于与所有其他列表相交的第一个列表,大约需要3分钟。 我怎样才能有效地做到这一点?可能使用其他语言/工具您应该在此处使用生成器表达式,它
set(a) & set(b)
其中a和b是在双循环中迭代得到的列表。
但这需要花费太多的时间。例如:对于与所有其他列表相交的第一个列表,大约需要3分钟。
我怎样才能有效地做到这一点?可能使用其他语言/工具您应该在此处使用生成器表达式,它们执行惰性计算并节省大量内存:
In [46]: from itertools import imap
In [47]: a = [[1,2,3], [2,3,4], [3,4,5]]
In [48]: reduce(set.intersection,imap(set,a))
Out[48]: set([3])
考虑到您的文件如下所示:
1 2 3
2 3 4
3 4 5
代码:
使用itertools.com组合:
您应该在此处使用生成器表达式,它们执行惰性计算并节省大量内存:
In [46]: from itertools import imap
In [47]: a = [[1,2,3], [2,3,4], [3,4,5]]
In [48]: reduce(set.intersection,imap(set,a))
Out[48]: set([3])
考虑到您的文件如下所示:
1 2 3
2 3 4
3 4 5
代码:
使用itertools.com组合:
第一个想法是首先构建所有集合一次,如果它们都适合内存,然后将它们相交
如果你真的需要30万条线与30万条线的所有交点,那无论如何都需要时间。也许你应该重新考虑你的问题。第一个想法是首先构建所有集合一次,如果它们都适合内存,然后将它们相交
如果你真的需要30万条线与30万条线的所有交点,那无论如何都需要时间。也许你应该重新考虑你的问题。我认为你可以通过创建一个反向索引来优化这个问题,也就是说,一个映射编号=>包含这个编号的行列表。例如,如果第5行、第100行、第200行出现10,则
10: [5, 100, 200]
要进一步优化此功能,可以将行列表存储为一组对:
10: set( (5,100), (5,200), (100,200) )
然后,要计算list_a+list_b的交集,只需找到其关联行列表包含list_a,list_b的所有数字。我认为您可以通过创建一个反向索引来优化此操作,即映射号=>包含此数字的行列表。例如,如果第5行、第100行、第200行出现10,则
10: [5, 100, 200]
要进一步优化此功能,可以将行列表存储为一组对:
10: set( (5,100), (5,200), (100,200) )
然后,要计算list_a+list_b的交集,只需查找其关联行列表包含list_a,list_b的所有数字。您是否正在查找一个intersect b intersect?你所说的相互交集是什么意思?300000 x 300000=900亿个列表。即使您设法计算出所有可能的组合,我也不知道您将如何存储它们。@thg435:我不想存储列表。我只是找到交点,做一些计算,然后扔掉那个列表。使用seta.intersectionb你希望交点中的哪一部分是空的?你是在找一个intersect b intersect?你所说的相互交集是什么意思?300000 x 300000=900亿个列表。即使您设法计算出所有可能的组合,我也不知道您将如何存储它们。@thg435:我不想存储列表。我只是找到交叉点,做一些计算,然后扔掉那个列表。使用seta.intersectionb你认为交叉点的哪一部分是空的?我不希望一次就得到所有的交叉点。我想一次只让两个列表相交。例如:list1&list2,然后list1&list3,然后list2&list1,然后list2&list3,然后list3&list1,然后list3&list2。@HappyMittal您在这里寻找的是itertools.compositions。@HappyMittal list1&list2和list2&list1实际上是同一件事。我不希望所有东西同时相交。我想一次只让两个列表相交。例如:list1&list2,然后list1&list3,然后list2&list1,然后list2&list3,然后list3&list1,然后list3&list2。@HappyMittal您在这里寻找的是itertools.compositions。@HappyMittal list1&list2和list2&list1实际上是一样的东西。