我有numpy向量,我想在限制索引范围内找到最大值。矢量可以包含NaN值。我还没有能够在numpy的最大函数中找到解决NaN&s和子范围的解决方案。 Python有解决方案吗?
示例:我希望数组中第7位和第11位之间的第二个最大值(5.)。
import numpy as np
b = np.array([3, np.nan, 5.3, 7., 8,5., 0, 1, 3, 5., 2.4, .1, .3, 0.5])
c = np.nanmax(a)
d = np.nanargmax(b)
我试着建立自己的功能;因为NaN的失败而失败了 - 而且它很丑陋。见下文。
def rightmax(vector,s,f):
l = 0
peak = 0
ml = 0
for val in vector:
if l < s or l >= f:
continue
elif val > peak:
peak = val
ml = l
l = l+1
return peak, ml
答案 0 :(得分:2)
听起来你想找到数组中的最后一个局部最大值。即在您的示例中,在位置4和9处分别存在两个局部最大值8和5.(基于0的阵列计数)。因此,您正在寻找5.,9的答案。假设我已经正确地解释了这一点,那么只是抓住最大值并不能得到答案。随着值沿向量上下移动,您需要找到最大值。
您可以使用scipy.signal中的argrelextrema来查找最大值。然而,如果没有一些处理,它就无法处理纳米值。
假设nan值不应影响结果,那么您可以通过在相邻值之间插值来安全地替换它们,例如使用简单的平均值。例如在您的示例数组中,您可以处理它以使用(5.3 + 3)/ 2替换np.nan。给4.15(这可以确保你不会意外地将nan推广到最小值或最大值,如果你假设一个非常小或非常大的值来替换它们可能会发生这种情况)。完成此操作后,您可以轻松应用argrelextrema:
import numpy as np
from scipy.signal import argrelextrema
# array processed to replace nan values
b = np.array([3, np.nan, 5.3, 7., 8,5., 0, 1, 3, 5., 2.4, .1, .3, 0.5])
mask = np.isnan(data)
b[mask] = np.interp(np.flatnonzero(mask), np.flatnonzero(~mask), b[~mask])
c = argrelextrema(b, np.greater)
maxIdx = c[-1] #last element of c
maxVal = b[maxIdx]
答案 1 :(得分:1)
你说你想用Python做这件事;这会为你处理事情吗? Python在其大多数内置函数中都忽略了NaN值。
import numpy as np
def local_max(a, start, finish):
local = a[start:finish+1]
loc_max = max(local)
loc_pos = local.index(loc_max) + start
return loc_max, loc_pos
data = [3, np.nan, 5.3, 7.0, 8, 5.0, 0, 1, 3, 5.0, 2.4, 0.1, 0.3, 0.5]
print local_max(data, 7, 11)
print local_max(data, 0, 5)