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