我想在数组中同时找到局部最小值和最大值。我试图使用Scipy的argrelextrema,但是我找不到任何关于所需比较器功能的文档。我试图写自己没有成功。我怎么能这样做?
我想这样做,但只调用argrelextrema
一次,而不是使用argrelmin
和argrelmax
两次迭代数据,因为我的数据很长,而且我有用它多次这样做:
import numpy as np
import scipy.signal as sg
data = [[xes], [ys]] #a long 2d array
max_places = np.array(sg.argrelmax(data[1]))[0]
min_places = np.array(sg.argrelmin(data[1]))[0]
extrema_places = np.contantenate((max_places, min_places))
答案 0 :(得分:1)
你的目标没有意义。
使用文档中的示例:
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测试为false)
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
返回True / False。
你是否正朝着两个方向寻找转折点?您可能想要使用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级迭代。