web-dev-qa-db-ja.com

x値とy値がnumpy配列として指定されている場合、すべてのローカルMaximaおよびMinimaを検索します

私は2つの配列xyを持っています:

x = np.array([6, 3, 5, 2, 1, 4, 9, 7, 8])
y = np.array([2, 1, 3, 5, 3, 9, 8, 10, 7])

私は次のように極小値と極大値のインデックスを見つけています:

sortId = np.argsort(x)
x = x[sortId]
y = y[sortId]
minm = np.array([])
maxm = np.array([])
while i < y.size-1:
   while(y[i+1] >= y[i]):
      i = i + 1

   maxm = np.insert(maxm, 0, i)
   i++
   while(y[i+1] <= y[i]):
      i = i + 1

   minm = np.insert(minm, 0, i)
   i++

このコードの問題は何ですか?答えはminima = [2, 5, 7]のインデックスとmaxima = [1, 3, 6]のインデックスである必要があります。

11
prtkp

このwhileループはまったく必要ありません。以下のコードは、必要な出力を提供します。すべての極小値とすべての極大値を見つけて、それぞれminmmaxmに格納します。注意:これを大きなデータセットに適用する場合は、最初に信号を平滑化してください。さもなければ、あなたは極端なトンに終わるでしょう。

import numpy as np
from scipy.signal import argrelextrema
import matplotlib.pyplot as plt

x = np.array([6, 3, 5, 2, 1, 4, 9, 7, 8])
y = np.array([2, 1, 3 ,5 ,3 ,9 ,8, 10, 7])

# sort the data in x and rearrange y accordingly
sortId = np.argsort(x)
x = x[sortId]
y = y[sortId]

# this way the x-axis corresponds to the index of x
plt.plot(x-1, y)
plt.show()
maxm = argrelextrema(y, np.greater)  # (array([1, 3, 6]),)
minm = argrelextrema(y, np.less)  # (array([2, 5, 7]),)

これは、上記のwhileループよりもはるかに効率的です。

プロットは次のようになります。 x値をシフトして、それらがminmおよびmaxm)で返されたインデックスに対応するようにしました。

enter image description here

SciPyバージョン1.1以降、 find_peaks を使用することもできます:

from scipy.signal import find_peaks

peaks, _ = find_peaks(y)

# this way the x-axis corresponds to the index of x
plt.plot(x-1, y)
plt.plot(peaks, y[peaks], "x")
plt.show()

それは

enter image description here

良い点は、最小ピーク高さ(例:8)も簡単に設定できることです。

peaks, _ = find_peaks(y, height=8)

# this way the x-axis corresponds to the index of x
plt.plot(x-1, y)
plt.plot(peaks, y[peaks], "x")
plt.show() 

enter image description here

高さが8未満であるため、最初のピークが除外されていることに注意してください。

さらに、ピーク間の最小距離も設定できます(例:5):

peaks, _ = find_peaks(y, distance=5)

# this way the x-axis corresponds to the index of x
plt.plot(x-1, y)
plt.plot(peaks, y[peaks], "x")
plt.show()

enter image description here

他の2つのピークまでの距離が5未満であるため、中央のピークは除外されます。

21
Cleb
x=np.array([6,3,5,2,1,4,9,7,8])
y=np.array([2,1,3,5,7,9,8,10,7])

sort_idx = np.argsort(x)
y=y[sort_idx]
x=x[sort_idx]
minm=np.array([],dtype=int)
maxm=np.array([],dtype=int)
length = y.size
i=0

while i < length-1:
    if i < length - 1:
        while i < length-1 and y[i+1] >= y[i]:
            i+=1

        if i != 0 and i < length-1:
            maxm = np.append(maxm,i)

        i+=1

    if i < length - 1:
        while i < length-1 and y[i+1] <= y[i]:
            i+=1

        if i < length-1:
            minm = np.append(minm,i)
        i+=1


print minm
print maxm

minmmaxmには、それぞれ最小値と最大値のインデックスが含まれています。

1
prtkp

これは正常に動作します。

Pythonは+= の代わりに ++

Whileループでiを使用する前に、何らかの値(この場合は0-)を割り当てる必要があります。これにより、エラーを回避するために値を初期化します。

import numpy as np

x=np.array([6,3,5,2,1,4,9,7,8])
y=np.array([2,1,3,5,3,9,8,10,7])


sortId=np.argsort(x)
x=x[sortId]
y=y[sortId]
minm = np.array([])
maxm = np.array([])
i = 0
while i < y.size-1:
   while(y[i+1] >= y[i]):
      i+=1

   maxm=np.insert(maxm,0,i)
   i+=1
   while(y[i+1] <= y[i]):
      i+=1

   minm=np.insert(minm,0,i)
   i+=1

print minm, maxm
0
Geeocode