Как рассчитать последовательные периоды во временной серии выше / ниже порога? - PullRequest
0 голосов
/ 02 июля 2019

У меня есть набор данных значений за годичный период, для которого я хочу обнаружить и посчитать периоды последовательных значений выше / ниже предварительно определенного порогового значения. Я хотел бы просто вернуть длину каждого периода последовательных значений выше / ниже порога. Я нашел в сети код, который почти точно выполняет то, что я хочу (показано ниже, функция под названием «fire_season_length»), за исключением того, что у него возникают проблемы с возвратом последнего последовательного периода до окончания набора данных (в конце года).

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

Вот функция, которую я использую для подсчета последовательных периодов выше / ниже порога:

def fire_season_length(ts, threshold):

    ntot_ts = ts.count() #total number of values in ts (timeseries)
    n_gt_threshold = ts[ts >= threshold].count() #number of values greater than threshold

    type_day = 0 #below threshold
    type_day = 1 #meets or exceeds threshold

    type_prev_day = 0 #initialize first day 
    storage_n_cons_days = [[],[]]   #[[cons days above threshold], [cons days below threshold]]
    n_cons_days = 0

    for cur_day in ts: #current day in timeseries

        if cur_day >= threshold:
            type_cur_day = 1
            if type_cur_day == type_prev_day: #if same as current day
                n_cons_days += 1
            else: #if not same as current day
                storage_n_cons_days[1].append(n_cons_days)
                n_cons_days = 1
            type_prev_day = type_cur_day
        else:
            type_cur_day = 0
            if type_cur_day == type_prev_day:
                n_cons_days += 1
            else:
                storage_n_cons_days[0].append(n_cons_days)
                n_cons_days = 1
            type_prev_day = type_cur_day



    return ntot_ts, n_gt_threshold, storage_n_cons_days

И это вывод, когда я запускаю временную серию через функцию; Я аннотировал график, чтобы показать, что существует 7 периодов последовательных значений, но массив, который возвращается [[13,185,30], [24, 78, 12]] (который указывает [[периоды выше порога]) , [периоды ниже порога]]) перечисляет только шесть таких периодов. Кажется, что период 7 не сообщается в выходных данных, что согласуется с выходом из других временных рядов, которые я также тестировал в этой функции. См. аннотированный сюжет здесь

Итак, мой вопрос: как мне заставить мой код вернуть последний период последовательных значений, даже если ряд значений не перевернулся, чтобы иметь другой знак (выше / ниже порога)?

1 Ответ

1 голос
/ 02 июля 2019

Вы можете сделать это, используя комбинацию накопления () и счетчика ():

import random
from itertools import accumulate
from collections import Counter

ts = [ random.randint(1,100) for _ in range(15) ]

treshold = 50
groups = accumulate([0]+[(a>=treshold) != (b>=treshold) for a,b in zip(ts,ts[1:])])
counts = sorted(Counter(groups).items())
above  = [ c for n,c in counts if (n%2==0) == (ts[0]>=treshold) ]
below  = [ c for n,c in counts if (n%2==0) != (ts[0]>=treshold) ]

print("data ",ts)
print("above",above)
print("below",below)

пример вывода:

data  [99, 49, 84, 69, 27, 88, 35, 43, 3, 48, 80, 14, 32, 97, 78]
above [1, 2, 1, 1, 2]
below [1, 1, 4, 2]

Это работает следующим образом:

  • Сначала определите позиции, где происходит смещение между верхом и низом.
  • Изменения состояния обозначены True (1), а неизменяемые позиции - False (0).
  • Совокупная сумма этих 1 и 0 будет давать серии различных значений для изменений с повторениями этих значений для позиций без изменения состояния.
  • Класс Counter затем используется для подсчета количества повторяющихся значений.Это соответствует количеству последовательных состояний, разбитых на отдельные изменения состояния.
  • Сортировка счетчиков восстанавливает хронологический порядок изменений состояния.
  • В зависимости от состояния первого элемента, все четные значения будут соответствовать состоянию выше или ниже, а нечетные значения будут противоположным.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...