我试图找出列表元素和列表中每个元素的所有元素之间的区别。我想这就是我所描述的?让我们用一个例子来代替:
idx = [1, 4, 8, 10, 22]基于这个问题,只要将元素压缩在一起就足够简单了,但这只会导致每个元素只进行一次成对比较,而我需要对每个元素进行多个成对比较。
我的做法是做以下工作:
diffs = [abs(i-j) for i in idx for j in idx]但这是难以置信的低效。计算以下所有元组的差异的最有效方法是什么?
comparisons = [(1,4), (1,8), (1,10), (1, 22),
(4,8), (4,10), (4,22),
(8,10, 8,22)]注意:
我更喜欢使用BasePython2.7的答案,但我也想知道如何使用Numpy来完成这个任务,因为我确信这个包可以使它变得更容易。
发布于 2016-12-31 18:48:23
您可以编写一个生成器:
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输出:
3
7
9
21
4
6
18
2
14
12这就产生了一个接一个的差异,内存开销很小。而且,使用@RoryDaulton的思想,这不会影响到冗余或已知为零的计算差异。
发布于 2016-12-31 18:45:22
请注意,您的结果实际上将包含n*n元素。因此,如果您的长度为25,039 (如注释中所述),则必须注意不要使用这6.3亿个元素访问MemoryError。
一种方法是选择numpy并选择一个足够小的dtype
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 ):
>>> diffs.nbytes
1_250_000_000如果您在int32上操作,您大概需要2.5GB才能保存结果--如果没有无限精度的整数范围,则默认为pythons (pythons默认),这将高达5GB,忽略了任何python对象开销。请注意,int16的值范围仅为32767,因此如果需要,您可能需要选择更大的dtype。
除了内存问题之外,就此类操作的效率而言,没有办法击败numpy。在我的电脑上大约需要1.2秒才能计算出25k×25k的差值。
如果需要差异小于某个值的发生次数,那么numpy再次提供了一个简单的解决方案:
num = np.sum(np.abs(diffs) < some_value) https://stackoverflow.com/questions/41410737
复制相似问题