Nei*_*ein 5 python numpy scipy
我想在数组中同时找到局部最小值和最大值。我尝试使用 Scipy 的 argrelextrema,但没有找到有关所需比较器函数的任何文档。我试图自己写,但没有成功。我怎么能这样做?
我想这样做,但只调用argrelextrema一次而不是用argrelminand迭代数据两次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))
Run Code Online (Sandbox Code Playgroud)
你的目标没有意义。
使用文档中的示例:
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),)
Run Code Online (Sandbox Code Playgroud)
这得到了局部最大值。更改为less以获得局部最小值。
In [202]: argrelextrema(x, np.less)
Out[202]: (array([1, 5], dtype=int32),)
Run Code Online (Sandbox Code Playgroud)
函数lambda可以代替np.greater:
In [204]: argrelextrema(x, lambda a,b: a>b)
Out[204]: (array([3, 6], dtype=int32),)
Run Code Online (Sandbox Code Playgroud)
我们可以将 > 和 < 用 or 组合起来,但这只会获取所有点(除了末端)。
In [205]: argrelextrema(x, lambda a,b: (a>b) | (a<b))
Out[205]: (array([1, 2, 3, 4, 5, 6], dtype=int32),)
Run Code Online (Sandbox Code Playgroud)
更改 的值,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),)
Run Code Online (Sandbox Code Playgroud)
但是假设你可以给它想要的功能,你想要什么样的结果?最大值和最小值串在一起作为一个数组、两个数组、还是一个二维数组?
np.array([1,3,5,6])
(np.array([3,6]), np.array([1,5]))
Run Code Online (Sandbox Code Playgroud)
刚刚意识到结果已经是一个元组,就像where每个维度一个数组。事实上,这就是它返回的内容:
results = _boolrelextrema(data, comparator,
axis, order, mode)
return np.where(results)
Run Code Online (Sandbox Code Playgroud)
任务的核心在于该_boolrelextrama功能;它大概返回一个类似 的数组data,但 True/False 基于comparator.
您是否正在寻找任一方向的转折点?你可能想玩order。
In [217]: argrelextrema(x, lambda a,b: (a>b) | (a<b), order=2)
Out[217]: (array([1, 3, 6], dtype=int32),)
Run Code Online (Sandbox Code Playgroud)
修改后,x这个 order 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),)
Run Code Online (Sandbox Code Playgroud)
argrelmin生成相同的plus和minus,但随后执行:
In [270]: np.where((x<plus) & (x<minus))
Out[270]: (array([1, 5], dtype=int32),)
Run Code Online (Sandbox Code Playgroud)
where在交织索引之前执行“或”步骤:
In [271]: np.where(((x<plus) & (x<minus)) | (x>plus) & (x>minus))
Out[271]: (array([1, 3, 5, 6], dtype=int32),)
Run Code Online (Sandbox Code Playgroud)
组合min_max可以节省 2 个take操作,但否则它会执行相同的 2 个比较器步骤。
请注意,所有这些操作都在编译代码中;数据数组上没有 Python 级别的迭代。
| 归档时间: |
|
| 查看次数: |
9480 次 |
| 最近记录: |