你的目标没有意义。
使用文档中的示例:
In [199]: from scipy.signal import argrelextrema
In [200]: x = np.array([2, 1, 2, 3, 2, 0, 1, 0])
In [201]: argrelextrema(x, np.greater)
Out[201]: (array([3, 6], dtype=int32),)
这会得到局部最大值。更改为 less 以获取局部最小值。
In [202]: argrelextrema(x, np.less)
Out[202]: (array([1, 5], dtype=int32),)
lambda 函数可以代替 np.greater 工作:
In [204]: argrelextrema(x, lambda a,b: a>b)
Out[204]: (array([3, 6], dtype=int32),)
我们可以将 > 和
In [205]: argrelextrema(x, lambda a,b: (a>b) | (a<b))
Out[205]: (array([1, 2, 3, 4, 5, 6], dtype=int32),)
更改x 的值,使两个相邻的值相同(因此 lambda 测试为假)
In [211]: x
Out[211]: array([2, 1, 2, 3, 2, 2, 1, 0])
In [212]: argrelextrema(x, lambda a,b: (a>b) | (a<b))
Out[212]: (array([1, 2, 3, 6], dtype=int32),)
但是假设你可以给它想要的功能,你想要什么样的结果?最大值和最小值串在一起作为一个数组,还是两个,还是一个二维数组?
np.array([1,3,5,6])
(np.array([3,6]), np.array([1,5]))
刚刚意识到结果已经是一个元组,比如where,每个维度一个数组。事实上,这就是它返回的内容:
results = _boolrelextrema(data, comparator,
axis, order, mode)
return np.where(results)
任务的重点在于_boolrelextrama 函数;它可能返回一个类似data 的数组,但基于comparator 的真/假。
您是否正在寻找一个转折点,无论是哪个方向?你可能想玩order。
In [217]: argrelextrema(x, lambda a,b: (a>b) | (a<b), order=2)
Out[217]: (array([1, 3, 6], dtype=int32),)
使用修改后的x,此订单 2 版本确实返回了两个极值。但我怀疑如果转弯之间的运行时间更长,它是否有效。
查看sg._peak_finding.py 中的完整代码(另请参阅文档中的[source] 链接)。 _boolrelextrema 使用 comparator 来测试 data 与 data 的几个转换版本。 mode 被np.take 使用。
那么详细
argrelmax 正在做:
In [262]: x = np.array([2, 1, 2, 3, 2, 0, 1, 0]) # data
In [263]: locs = np.arange(0,len(x)) # all indices
In [264]: plus=np.take(x,locs+1,mode='clip') # shift up, with 'clip'
In [265]: minus=np.take(x,locs-1,mode='clip') # shift down
In [266]: plus
Out[266]: array([1, 2, 3, 2, 0, 1, 0, 0])
In [267]: minus
Out[267]: array([2, 2, 1, 2, 3, 2, 0, 1])
In [268]: (x>plus) & (x>minus) # compare x with shifted arrays
Out[268]: array([False, False, False, True, False, False, True, False], dtype=bool)
In [269]: np.where(_)
Out[269]: (array([3, 6], dtype=int32),)
argrelmin 生成相同的 plus 和 minus,但随后会:
In [270]: np.where((x<plus) & (x<minus))
Out[270]: (array([1, 5], dtype=int32),)
在where 交织索引之前执行“或”步骤:
In [271]: np.where(((x<plus) & (x<minus)) | (x>plus) & (x>minus))
Out[271]: (array([1, 3, 5, 6], dtype=int32),)
合并的 min_max 可以节省 2 个 take 操作,但除此之外它执行相同的 2 个比较器步骤。
请注意,所有这些操作都在编译后的代码中;数据数组上没有 Python 级迭代。