在numpy数组中获得最大上升幅度



我正试图编写一个函数来计算每个数组中最大的优势。下面的函数在最大值和最小值之间进行计算,但它没有得到我想要的预期输出。calc(C)的结果应该是89,因为11, -23, 45, 11, 66的值从阵列中的-23 to 66上升,导致上升为89点。我该如何修复下面的功能?示例代码来自:发布

def calc(arr):
try:
acc_max = np.minimum.accumulate(arr)
result = (arr + acc_max).min()
dip_idx = (arr + acc_max).argmin()
max_idx= arr[:dip_idx].argmax()
print("Result: {} Between Values: {},{} Indexes: {},{}".format(result, arr[max_idx],arr[dip_idx],max_idx,dip_idx))
return result
except:
print("No Upside")
A = np.array([2,5,44,-12,3,-5])
B = np.array([10,-110,23,45,66,30,2,12])
C = np.array([10,11,-23,45,11,66,45,4,12])
D = np.array([8,7,6,5])
E = np.array([10,5,6,8])
calc(A)
calc(B)
calc(C)
calc(D)
calc(E)

输出

A Result: -24 Between Values: 44,-12 Indexes: 2,3
B Result: -220 Between Values: 10,-110 Indexes: 0,1
C Result: -46 Between Values: 11,-23 Indexes: 1,2
C No Upside
E Result: 10 Between Values: 10,5 Indexes: 0,3

预期输出:

A Result: 42 Between Values: 2,44 Indexes: 0,2
B Result: 176 Between Values: -110,66 Indexes: 1,4
C Result: 89 Between Values: -23,66 Indexes: 2,5
C No Upside
E Result: 3 Between Values: 5,8 Indexes: 1,3

我认为这应该有效,但我确实建议了一些更好的变量名称(见下文(,我保留了您的名称以显示差异。

def calc(arr):
try:
acc_max = np.minimum.accumulate(arr)
result = (arr - acc_max).max()
dip_idx = (arr - acc_max).argmax()
max_idx= arr[:dip_idx].argmin()
print("Result: {} Between Values: {},{} Indexes: {},{}".format(result, arr[max_idx],arr[dip_idx],max_idx,dip_idx))
return result
except:
print("No Upside")

我将arr + acc_max更改为arr - acc_max,将arr[:dip_idx].argmin()更改为arr[:dip_idx].argmax()

解释:acc_max将是迄今为止在数组中找到的最低数字。因此,您要做的是从原始数组中减去这个数组,以获得每个元素与数组中迄今为止找到的最小数之间的diff,即arr - acc_max将包含所有这些diff。

然后(arr - acc_max).max()将为您提供最大diff(您正在寻找(,即最大增益。因此,result将保持最大增益的值,而dip_idx将保持实现最大增益的数值的索引。

max_idx= arr[:dip_idx].argmin()然后将在达到最大增益值之前找到阵列的最小值,即这将是";"开始";增益。

因此,通过对变量进行更好的命名:

def calc(arr):
try:
min_so_far = np.minimum.accumulate(arr)
max_gain = (arr - min_so_far).max()
max_gain_end_idx = (arr - min_so_far).argmax()
max_gain_start_idx= arr[:max_gain_end_idx].argmin()
print("Result: {} Between Values: {},{} Indexes: {},{}".format(          max_gain,arr[max_gain_end_idx],arr[max_gain_start_idx],max_gain_start_idx,max_gain_end_idx)
)
return max_gain
except:
print("No Upside")

这是一个典型的例子,说明当你在不试图理解的情况下复制和粘贴一堆代码时会发生什么

acc_max = np.minimum.accumulate(arr)

为什么最低运行要求被称为acc_max?另一件事是,你的代码不能在任何地方抛出错误,如果你粘贴了一个正确的MCVE,你就会注意到这一点。

正确的答案是,你想累积运行的最小值,从数组中减去它,然后找到结果的最大值。当整个数组单调递减时,您没有结果,这将导致np.minimum.accumulate返回arr,并且差异在任何地方都为零。

def calc(arr):
running_min = np.minimum.accumulate(arr)
delta = arr - running_min
if not delta.any():
print('No upswing')
return None
max_idx = delta.argmax()
result = delta[max_idx]
min_idx = arr[:max_idx].argmin()
print(f'Result: {result} Between values {arr[min_idx]}, {arr[max_idx]} at indices {min_idx}, {max_idx}')
return result

这将为所有测试输入生成预期结果。

最新更新