Подсчет пиков во временном ряду - PullRequest
3 голосов
/ 09 марта 2019

Я считаю количество пиков и впадин в массиве numpy.

У меня есть такой массив:

stack = np.array([0,0,5,4,1,1,1,5,1,1,5,1,1,1,5,1,1,5,1,1,5,1,1,5,1,1,5,1,1])

На графике эти данные выглядят примерно так:

Time Series plot of 'stack'array

Я ищу, чтобы найти число пиков в этом временном ряду:

Это мой код, который хорошо работает для примера, подобного этому, где есть четкие пики и впадины в представлении временных рядов. Мой код возвращает индексы массива, в котором были найдены пики.

#example
import numpy as np
from scipy.signal import argrelextrema

stack = 
np.array([0,0,5,4,1,1,1,5,1,1,5,1,1,1,5,1,1,5,1,1,5,1,1,5,1,1,5,1,1])

# for local maxima
y = argrelextrema(stack, np.greater)

print(y)

Результат:

(array([ 2,  7, 10, 14, 17, 20, 23, 26]),)

Было найдено 8 четких пиков, которые можно правильно подсчитать.

Мое решение не работает с данными, которые менее четкие и более грязные.

Массив ниже не работает и не находит нужные мне пики:

array([ 0.        ,  5.70371806,  5.21210157,  3.71144767,  3.9020162 ,
    3.87735984,  3.89030171,  6.00879918,  4.91964227,  4.37756275,
    4.03048542,  4.26943028,  4.02080471,  7.54749062,  3.9150576 ,
    4.08933851,  4.01794766,  4.13217794,  4.15081972,  8.11213474,
    4.6561735 ,  4.54128693,  3.63831552,  4.3415324 ,  4.15944019,
    8.55171441,  4.86579459,  4.13221943,  4.487663  ,  3.95297979,
    4.35334706,  9.91524674,  4.44738182,  4.32562141,  4.420753  ,
    3.54525697,  4.07070637,  9.21055852,  4.87767969,  4.04429321,
    4.50863677,  3.38154581,  3.73663523,  3.83690315,  6.95321174,
    5.11325128,  4.50351938,  4.38070175,  3.20891173,  3.51142661,
    7.80429569,  3.98677631,  3.89820773,  4.15614576,  3.47369797,
    3.73355768,  8.85240649,  6.0876192 ,  3.57292324,  4.43599135,
    3.77887259,  3.62302175,  7.03985076,  4.91916556,  4.22246518,
    3.48080777,  3.26199699,  2.89680969,  3.19251448])

На графике эти данные выглядят так:

Data 2

И тот же код возвращает:

(array([ 1,  4,  7, 11, 13, 15, 19, 23, 25, 28, 31, 34, 37, 40, 44, 50, 53,
   56, 59, 62]),)

Этот вывод неправильно считает точки данных как пики.

Идеальный выход

Идеальный вывод должен возвращать количество четких пиков, 11 в этом случае, которые расположены по индексам:

[1,7,13,19,25,31,37,44,50,56,62]

Я полагаю, что моя проблема возникает из-за агрегированной природы функции argrelextrema.

Ответы [ 2 ]

2 голосов
/ 10 марта 2019

Вы можете использовать некоторый порог, чтобы найти пики:

prev = stack[0] or 0.001
threshold = 0.5
peaks = []

for num, i in enumerate(stack[1:], 1):
    if (i - prev) / prev > threshold:
        peaks.append(num)
    prev = i or 0.001

print(peaks)
# [1, 7, 13, 19, 25, 31, 37, 44, 50, 56, 62]
1 голос
/ 10 марта 2019

Похоже, argrelextrema дает вам большую часть пути. У него есть все пики, которые вы хотите, но есть и некоторые дополнительные. Вам нужно придумать критерии, подходящие для вашего случая, и отфильтровать пики, которые вам не нужны.

Например, если вы не хотите, чтобы пики были меньше 5, вы можете сделать это:

In [17]: result = argrelextrema(a, np.greater)                                                           

In [18]: result                                                                                          
Out[18]: 
(array([ 1,  4,  7, 11, 13, 15, 19, 23, 25, 28, 31, 34, 37, 40, 44, 50, 53,
        56, 59, 62]),)

In [19]: result[0][a[result[0]] > 5]                                                                     
Out[19]: array([ 1,  7, 13, 19, 25, 31, 37, 44, 50, 56, 62])
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...