首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >有效地查找列表元素中的差异

有效地查找列表元素中的差异
EN

Stack Overflow用户
提问于 2016-12-31 18:20:33
回答 2查看 110关注 0票数 3

我试图找出列表元素和列表中每个元素的所有元素之间的区别。我想这就是我所描述的?让我们用一个例子来代替:

代码语言:javascript
复制
idx = [1, 4, 8, 10, 22]

基于这个问题,只要将元素压缩在一起就足够简单了,但这只会导致每个元素只进行一次成对比较,而我需要对每个元素进行多个成对比较。

我的做法是做以下工作:

代码语言:javascript
复制
diffs = [abs(i-j) for i in idx for j in idx]

但这是难以置信的低效。计算以下所有元组的差异的最有效方法是什么?

代码语言:javascript
复制
comparisons = [(1,4), (1,8), (1,10), (1, 22), 
               (4,8), (4,10), (4,22), 
               (8,10, 8,22)]

注意:

我更喜欢使用BasePython2.7的答案,但我也想知道如何使用Numpy来完成这个任务,因为我确信这个包可以使它变得更容易。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2016-12-31 18:48:23

您可以编写一个生成器:

代码语言:javascript
复制
idx = [1, 4, 8, 10, 22]

def differences(nums):
    n = len(nums)
    for i in xrange(n-1):
        for j in xrange(i+1,n):
            yield abs(nums[i]-nums[j])

for d in differences(idx): print d

输出:

代码语言:javascript
复制
3
7
9
21
4
6
18
2
14
12

这就产生了一个接一个的差异,内存开销很小。而且,使用@RoryDaulton的思想,这不会影响到冗余或已知为零的计算差异。

票数 4
EN

Stack Overflow用户

发布于 2016-12-31 18:45:22

请注意,您的结果实际上将包含n*n元素。因此,如果您的长度为25,039 (如注释中所述),则必须注意不要使用这6.3亿个元素访问MemoryError

一种方法是选择numpy并选择一个足够小的dtype

代码语言:javascript
复制
import numpy as np
arr = np.array(your_list, dtype=np.int16)
diffs = arr[:, None] - arr   # this will be a 25039 x 25039 array containing your desired differences.

即使使用np.int16,您也需要大量内存(这里使用的数组大小为25000 ):

代码语言:javascript
复制
>>> diffs.nbytes
1_250_000_000

如果您在int32上操作,您大概需要2.5GB才能保存结果--如果没有无限精度的整数范围,则默认为pythons (pythons默认),这将高达5GB,忽略了任何python对象开销。请注意,int16的值范围仅为32767,因此如果需要,您可能需要选择更大的dtype。

除了内存问题之外,就此类操作的效率而言,没有办法击败numpy。在我的电脑上大约需要1.2秒才能计算出25k×25k的差值。

如果需要差异小于某个值的发生次数,那么numpy再次提供了一个简单的解决方案:

代码语言:javascript
复制
num = np.sum(np.abs(diffs) < some_value) 
票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/41410737

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档