在 Python 列表中找到 "x" 个最大的差异

Find "x" greatest differences in Python list

假设我有一个数据列表...例如股票价格,我想了解更多关于列表中每个元素之间的差异 - 特别是最大的差异。在这种情况下,它将找到表现出最大变化(即最大收益或损失)的 2 个价格。

现在,我不只是想找到 奇异 最大的差异。我想找出 5 个最大的差异 - 用于计算差异的所有 5 对数字都是唯一的,并且不会收敛于同一个解决方案。

可以做到这一点的一种方法是使用嵌套的 for 循环,如下所示:

nums = [1,2,3,4,5]

for i in nums:
    for x in nums:
        return x-i

但是我觉得这个方法很笨拙,不能解决手头的问题。有一个更好的方法吗?谢谢!

编辑:

感兴趣者的解决方案

我使用@Chris_Rands答案的修改版本来解决这个问题。基本上,此函数只是找到一个最大的差异,然后从原始列表中删除每个元素并执行此过程,直到只剩下 1 个元素(当您找不到另一个差异时)。结果是一个元组数组,其中包含与数据集最大差异的 100% 唯一对:

from itertools import combinations
from heapq import nlargest

nums = [98,34,513,352,3523,308,13]

def findTrades(list_, amount):
    Trades_ = []

    while len(list_) >= 2:
        res = nlargest(1, combinations(list_, 2), key = lambda x: abs(x[0]-x[1]))
        Trades_.append(res)
        for i in res[0]:
            list_ = [x for x in list_ if x != i]

    return sorted(Trades_)[-amount:]

print (findTrades(nums, 3))

我将遍历列表一次并找到列表中的 3 个最大数字和列表中的 3 个最小数字。找出所有这些数字之间的差异,并取 3 个最大的。这将是高效的,并确保您找到前 5 个最大的差异。

这是一个接受列表/元组和 returns 5 个最大差异的函数。请注意,除了内置之外,这不使用任何其他依赖项。

用法:
differences(list_, length)
list_ 是您要检查的输入列表。
length 是您要记录的差异数。

def differences(list_, length):
    diffs = list(0 for _ in range(length))
    for i, j in enumerate(list_):
        for k in list_[i + 1:]:
            if max(j, k) - min(j, k) > min(diffs):
                diffs[0] = max(j, k) - min(j, k)
                diffs = sorted(diffs)
    return diffs

最大的 5 将被返回。如果列表中只有 3 个项目产生 3 个差异,则最后两个将为 0,因为您无法使用此代码获得负差异。

如果我理解正确的话:

from operator import sub
from itertools import combinations

gen = sorted(set(abs(sub(*tup)) for tup in combinations(nums, 2)), reverse=True)

gen

[4, 3, 2, 1]

采用 cartisean product 并使用 max:

from itertools import combinations 
nums = [1,2,3,4,5]
max(combinations(nums,2), key=lambda t: abs(t[0]-t[1]))
# (1,5)

如果您希望它们按不同排序:

sorted(combinations(nums,2), key=lambda t: abs(t[0]-t[1]), reverse=True)
[(1, 5), (1, 4), (2, 5), (1, 3), (2, 4), (3, 5), (1, 2), (2, 3), (3, 4), (4, 5)]

这里x=3。使用 heapq.nlargest 优于对 x.

的小值进行排序
>>> from itertools import combinations
>>> from heapq import nlargest
>>> nlargest(3, combinations(nums, 2), key = lambda x: abs(x[0]-x[1]))
[(1, 5), (1, 4), (2, 5)]

您可以尝试使用矩阵:

l = np.array([1,2,3,4])
a = np.tile(l,(len(l),1))
a - a.T

这将为您提供每两对元素之间的差异。现在您可以选择最大的 n 对。

b.ravel()[np.argsort(b.ravel())][-4:] 会给你最大的 4 个值

array([1, 2, 2, 3])

sol 包含所有五个最大的差异。 我每次迭代时都会替换最小差异。应该简单易懂。 (我没有检查边缘情况和其他问题)

lis=[1,2,6,3,76,44,98,23,56,87,23,65,19,73]
sol=[0,0,0,0,0]
for i in range(len(lis)):
  for j in range(len(lis)):
    if abs(lis[i]-lis[j])>min(sol):
      sol[sol.index(min(sol))]=lis[i]-lis[j]

print(sol)

#returned this [86, 97, 92, 96, 95]