【发布时间】:2019-04-27 05:39:38
【问题描述】:
我希望有一个函数可以检测数组中的局部最大值/最小值(即使有一组局部最大值/最小值)。示例:
给定数组
test03 = np.array([2,2,10,4,4,4,5,6,7,2,6,5,5,7,7,1,1])
我想要一个类似的输出:
set of 2 local minima => array[0]:array[1]
set of 3 local minima => array[3]:array[5]
local minima, i = 9
set of 2 local minima => array[11]:array[12]
set of 2 local minima => array[15]:array[16]
从示例中可以看出,不仅检测到奇异值,还检测到局部最大值/最小值集。
我知道在this question 中有很多好的答案和想法,但没有一个能够完成所描述的工作:其中一些简单地忽略了数组的极值点,并且都忽略了局部最小值/最大值的集合。
在问这个问题之前,我自己写了一个函数,它完全符合我上面描述的功能(该函数在这个问题的末尾:local_min(a)。通过我所做的测试,它可以正常工作)。
问题:但是,我也确信这不是使用 Python 的最佳方式。是否有我可以使用的内置函数、API、库等?还有其他功能建议吗?单行指令?一个完整的矢量解决方案?
def local_min(a):
candidate_min=0
for i in range(len(a)):
# Controlling the first left element
if i==0 and len(a)>=1:
# If the first element is a singular local minima
if a[0]<a[1]:
print("local minima, i = 0")
# If the element is a candidate to be part of a set of local minima
elif a[0]==a[1]:
candidate_min=1
# Controlling the last right element
if i == (len(a)-1) and len(a)>=1:
if candidate_min > 0:
if a[len(a)-1]==a[len(a)-2]:
print("set of " + str(candidate_min+1)+ " local minima => array["+str(i-candidate_min)+"]:array["+str(i)+"]")
if a[len(a)-1]<a[len(a)-2]:
print("local minima, i = " + str(len(a)-1))
# Controlling the other values in the middle of the array
if i>0 and i<len(a)-1 and len(a)>2:
# If a singular local minima
if (a[i]<a[i-1] and a[i]<a[i+1]):
print("local minima, i = " + str(i))
# print(str(a[i-1])+" > " + str(a[i]) + " < "+str(a[i+1])) #debug
# If it was found a set of candidate local minima
if candidate_min >0:
# The candidate set IS a set of local minima
if a[i] < a[i+1]:
print("set of " + str(candidate_min+1)+ " local minima => array["+str(i-candidate_min)+"]:array["+str(i)+"]")
candidate_min = 0
# The candidate set IS NOT a set of local minima
elif a[i] > a[i+1]:
candidate_min = 0
# The set of local minima is growing
elif a[i] == a[i+1]:
candidate_min = candidate_min + 1
# It never should arrive in the last else
else:
print("Something strange happen")
return -1
# If there is a set of candidate local minima (first value found)
if (a[i]<a[i-1] and a[i]==a[i+1]):
candidate_min = candidate_min + 1
注意:我尝试用一些 cmets 来丰富代码,让大家了解我的工作。我知道我建议的功能是 不干净,只打印可以存储和返回的结果 在末尾。它是为了举例而写的。我提出的算法应该是O(n)。
更新:
有人建议导入from scipy.signal import argrelextrema 并使用如下函数:
def local_min_scipy(a):
minima = argrelextrema(a, np.less_equal)[0]
return minima
def local_max_scipy(a):
minima = argrelextrema(a, np.greater_equal)[0]
return minima
拥有这样的东西是我真正想要的。但是,当局部最小值/最大值的集合具有两个以上的值时,它就不能正常工作。例如:
test03 = np.array([2,2,10,4,4,4,5,6,7,2,6,5,5,7,7,1,1])
print(local_max_scipy(test03))
输出是:
[ 0 2 4 8 10 13 14 16]
当然在test03[4] 我有一个最小值而不是最大值。如何解决此行为? (我不知道这是否是另一个问题,或者这是否是提出问题的正确地方。)
【问题讨论】:
-
有趣的问题,快速搜索似乎表明没有预先构建的解决方案。但是,为此设计一个简约的解决方案应该足够简单。我可以想到两种方法。让我尝试实现一个,看看它是否像我认为的那样干净。
-
你想如何处理egdes?
标签: python arrays python-3.x algorithm numpy