我希望以2种不同长度的字典形式比较大量数据。 (编辑)
post = {0: [0.96180319786071777, 0.37529754638671875],
10: [0.20612385869026184, 0.17849941551685333],
20: [0.20612400770187378, 0.17510984838008881],...}
pre = {0: [0.96180319786071777, 0.37529754638671875],
1: [0.20612385869026184, 0.17849941551685333],
2: [0.20612400770187378, 0.17510984838008881],
5065: [0.80861318111419678, 0.76381617784500122],...}
我们需要得到的答案是5065:[0.80861318111419678,0.76381617784500122]。这是基于我们只是比较价值而不是指数的事实。
我只使用此键值对来记住数据序列。如果需要,可以用列表/集替换数据类型。我需要找出关键:与字典不相同的元素的值(索引和值)对。
我使用的代码非常简单..
new = {}
found = []
for i in range(0, len(post)):
found= []
for j in range(0, len(pre)):
if post[i] not in pre.values():
if post[i] not in new:
new[i] = post[i]
found.append(j)
break
if found:
for f in found: pre.pop(f)
new {}包含我需要的元素。 我面临的问题是这个过程太慢了。处理有时需要一个多小时。有时数据可能会大得多。我需要它更快。
有没有一种有效的方法来实现我想要实现的目标?除非绝对必要,否则除了那些与python 2.5(64位)捆绑在一起的外部软件包之外我不想依赖外部软件包。
谢谢大家。
答案 0 :(得分:5)
这基本上是set
的设计目标(计算项目集的差异)。唯一的问题是你放入set
的东西需要是可以清洗的,而list
则不是。但是,tuple
是,所以如果你转换成那个,你可以把它们放到一个集合中:
post_set = set(tuple(x) for x in post.itervalues())
pre_set = set(tuple(x) for x in pre.itervalues())
items_in_only_one_set = post_set ^ pre_set
有关set
s的更多信息:http://docs.python.org/library/stdtypes.html#set
要在计算差异后获取原始索引,您可能需要的是生成反向查找表:
post_indices = dict((tuple(v),k) for k,v in post.iteritems())
pre_indices = dict((tuple(v),k) for k,v in pre.iteritems())
然后你可以通过字典获取一个给定的元组并查找其索引:
index = post_indices.get(a_tuple, pre_indices.get(a_tuple))
答案 1 :(得分:1)
您的问题可能是嵌套for
循环与range()
的使用相结合,每次创建一个新的list
可能会很慢。您可能会通过直接迭代pre
和post
获得一些自动加速,并避免以嵌套方式执行此操作。
post = {0: [0.96180319786071777, 0.37529754638671875],
10: [0.20612385869026184, 0.17849941551685333],
20: [0.20612400770187378, 0.17510984838008881]}
pre = {0: [0.96180319786071777, 0.37529754638671875],
1: [0.20612385869026184, 0.17849941551685333],
2: [0.20612400770187378, 0.17510984838008881],
5065: [0.80861318111419678, 0.76381617784500122]}
'''Create sets of values, independent of dict key for O(1) lookup'''
post_set=set(map(tuple, post.values()))
pre_set=set(map(tuple, pre.values()))
'''Iterate through each structure only once, filtering items that are found in
the sets we created earlier, updating new_diff'''
from itertools import ifilterfalse
new_diff=dict(ifilterfalse(lambda x: tuple(x[1]) in pre_set, post.items()))
new_diff.update(ifilterfalse(lambda x: tuple(x[1]) in post_set, pre.items()))
new_diff
现在为dict
,因此在post
和pre
中找不到每个值,并保留原始索引。
>>> print new_diff
{5065: [0.80861318111419678, 0.76381617784500122]}