Рассчитать расстояние между знаками изменения в выборочных данных

Я хочу восстановить периоды, которые находятся в массиве выборочных данных:

signal = [45, 46, -12, -12.5, 32, 35, 34, 25, 23, -23, -65, -3, 43, 23]

Я хочу посчитать размер периода. Период начинается с положительного числа и перемещается к отрицательным числам, а затем возвращается к положительному числу.

Например:

period1=[45 46 -12 -12.5 32]  # length=5
period2=[32 35 34 25 23 -23 -65 -3 43]  # length=8

Как это может быть сделано?

1 ответ

Решение

Хитрость заключается в том, чтобы дважды использовать numpy.diff(). Первый diff может использоваться, чтобы найти пересечения знака. Второй дифференциал может быть использован, чтобы найти расстояние между этими пересечениями.

Код:

import numpy as np

# put the data into a numpy array
signal = np.array(
    [45, 46, -12, -12.5, 0, 32, 35, 34, 25, 23, -23, -65, -3, 43, 23])

# consider zeros to be negative, since we are looking for return to positive
signal[np.where(signal == 0.0)] = -1e-100

# find any returns to positive
return_to_positive = 1 + np.where(2 == np.diff(np.sign(signal)))[0]

# the periods are the distance between `return to positives`
periods = np.diff(return_to_positive)

Выход:

>>> print(periods)
[8]

Магия объяснила:

Сначала нужно убедиться, что в наших данных нет нулей. Это потому, что мы хотим иметь чистые пересечения нуля. Установите любые нули чуть меньше нуля, так как мы хотим, чтобы первое положительное значение было началом периода.

# consider zeros to be negative, since we are looking for return to positive
signal[np.where(signal == 0.0)] = -1e-100

Возьмите знак сигнала, а затем измените его. Везде это 2 где сигнал переходит от отрицательного к положительному. добавлять 1 к показателям, потому что предыдущий diff удалил один элемент из массива. (Примечание, pandas делает это для вас)

# find the indices for any returns to positive
return_to_positive = 1 + np.where(2 == np.diff(np.sign(signal)))[0]

Наконец, возьмите расстояние между индексами для каждого пересечения нуля, чтобы получить периоды.

# the periods are the distance between `return to positives`
periods = np.diff(return_to_positive)
Другие вопросы по тегам