从Python列表中有效地删除非常接近重复的内容

时间:2013-09-14 14:03:55

标签: python list python-2.7 duplicates

背景:我的Python程序处理相对大量的数据,可以在程序中生成或导入。然后处理数据,并且在这些过程之一中,有意地复制数据然后进行操作,清理重复数据然后返回到程序以供进一步使用。我正在处理的数据非常精确(最多16位小数),并且将此精度保持在至少14dp是至关重要的。然而,数学运算当然可以返回我的浮点数的微小变化,这样两个值与14dp相同,但可能会略微变化到16dp,因此意味着内置set()函数无法正确删除这样的'重复'(我使用这种方法来构思这个想法,但是对于完成的程序它并不令人满意)。我还应该指出,我可能会忽略一些简单的事情!我只是想知道其他人想出了什么:)

问题:
什么是从潜在中删除非常接近重复的最有效方法非常大的数据集?

我的尝试:我已经尝试将值本身四舍五入到14dp,但这当然不能令人满意,因为这会导致更大的错误下线。我有一个解决这个问题的潜在解决方案,但我不相信它尽可能高效或“pythonic”。我的尝试涉及查找与x dp匹配的列表条目的索引,然后删除其中一个匹配的条目。

提前感谢您的任何建议!如果你有什么想澄清的话,请告诉我,当然如果我忽略了一些非常简单的事情(我可能会在某个地方,我过度思考它)。

< strong>澄清'重复':
我的一个'重复'条目示例:603.73066958946424,603.73066958946460,解决方案将删除其中一个值。

关于decimal.Decimal的注意事项
如果确保所有导入的数据都没有一些近似重复项(通常这样做),这可能会有效。

2 个答案:

答案 0 :(得分:4)

如果你正在处理大量数据,你真的想要使用NumPy。我就是这样做的:

导入NumPy:

import numpy as np

生成8000个高精度浮点数(128位就足够了,但请注意我将random的64位输出转换为128只是为了伪造它。在这里使用你的真实数据。):

a = np.float128(np.random.random((8000,)))

查找圆角数组中唯一元素的索引:

_, unique = np.unique(a.round(decimals=14), return_index=True)

从原始(非圆形)数组中获取这些索引:

no_duplicates = a[unique]

答案 1 :(得分:3)

为什么不创建一个将14dp值映射到相应的完整16dp值的字典:

d = collections.defaultdict(list)

for x in l:
    d[round(x, 14)].append(x)

现在,如果您只想要“唯一”(根据您的定义)值,您可以

unique = [v[0] for v in d.values()]