2015-10-27 60 views
0

我有numpy向量,我想在限制索引範圍內找到最大值。該向量可能包含NaN值。我一直無法在numpy的max函數中找到處理NaN和子範圍的解決方案。 Python是否有解決方案?函數查找本地最大值

示例:我想要第二個最大值(5.),位於數組中的第7個和第11個位置之間。

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 

回答

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) 
+0

是的,那就是我在找的東西。 ty – Claudia

+0

我收到一條錯誤消息:「對象沒有屬性索引」。它會是什麼? – Claudia

+0

你正在運行我的代碼?你有什麼版本的Python?礦在2.7(最低公分母)。 – Prune

2

這聽起來像是你想找到數組中的最後一個局部最大值。即在你的例子中,在位置4和9分別有兩個局部最大值8和5.(基於0的陣列計數)。所以你正在尋找5,9的答案。假設我已經正確地解釋了這一點,那麼只是抓住最大值不會得到答案。你需要找到最大值,因爲這些值沿矢量向上和向下。

您可以使用scipy.signal中的argrelextrema來查找最大值。但是,如果沒有一些處理,它不會處理nan值。

假設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] 
+0

是的,那是我需要做的。我必須在特定的時間範圍內遇到最大值。大多數時候它是最後的最大值。感謝您向我展示agrelextrema功能。不幸的是我也必須處理nan。 – Claudia

+1

我沒有添加nan處理 - 這很容易做到這一點,我已經給出了一個合理的方法,不會影響向量中最後局部最大值的正確識別。像這樣的東西應該這樣做:mask = np.isnan(b) b [mask] = np.interp(np.flatnonzero(mask),np.flatnonzero(〜mask),b [〜mask])。我已經在上面更新了我的答案。 – nempnett

+0

你的第一個方法已經很棒了。在我的情況下,我有幾個矩陣,我不能一個接一個地處理nan。所以你的第二種方法更好。我會盡快測試它。但是,請檢查maxIdx和maxVal ...它們將以最大值和索引返回整個元組。謝謝你的回答。 – Claudia