Как применить нижний и верхний порог к массиву NumPy? - PullRequest
0 голосов
/ 06 июня 2018

У меня есть следующий массив

array = np.array([-0.5, -2, -1, -0.5, -0.25, 0, 0, -2, -1, 0.25, 0.5, 1, 2])

, и я хотел бы применить два порога, так что все значения ниже -1.0 установлены на 1 и все значения выше -0.3 установлены на 0.Для значений между ними должно применяться следующее правило: если последнее значение было ниже -1.0, тогда оно должно быть 1, но если последнее значение было выше -0.3, то оно должно быть 0.

Для приведенного выше примера массива выходные данные должны быть

target = np.array([0, 1, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0])

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

Я пытался добиться этого путем перебора массива и использования while внутри цикла for, чтобы найти следующий случай, когда значение равновыше порога, но он не работает:

array = np.array([-0.5, -2, -1, -0.5, -0.25, 0, 0, -2, -1, 0.25, 0.5, 1, 2])

p = []

def function(array, p):
    for i in np.nditer(array):
       if i < -1: 
          while i <= -0.3:
            p.append(1)
            i += 1
          else:
            p.append(0)
            i += 1
    return p

a = function(array, p)
print(a)

Как я могу применить два порога к моему массиву, как описано выше?

1 Ответ

0 голосов
/ 06 июня 2018

То, что вы пытаетесь достичь, называется «порог с гистерезисом».Для этого я адаптировал очень хороший алгоритм из этого ответа :

Учитывая ваши тестовые данные,

import numpy as np
array = np.array([-0.5, -2, -1, -0.5, -0.25, 0, 0, -2, -1, 0.25, 0.5, 1, 2])

вы определяете, какие значения ниже первого порога -1.0 и выше второго порога -0.3:

low_values = array <= -1.0
high_values = array >= -0.3

Это значения, для которых вы знаете результат: либо 1, либо 0.Для всех других значений это зависит от его соседей.Таким образом, известны все значения, для которых low_values или high_values равно True.Вы можете получить индексы всех известных элементов с помощью:

known_values = high_values | low_values
known_idx = np.nonzero(known_values)[0]

Чтобы найти результат для всех неизвестных значений, мы используем функцию np.cumsum в массиве known_values.Логические значения интерпретируются как 0 или 1, поэтому это дает нам следующий массив:

acc = np.cumsum(known_values)

, что приведет к следующему для вашего примера: [ 0 1 2 2 3 4 5 6 7 8 9 10 11].Теперь known_idx[acc - 1] будет содержать индекс последнего известного значения для каждой точки.С low_values[known_idx[acc - 1]] вы получите True, если последнее известное значение было ниже -1.0, и False, если оно было выше -0.3:

result = low_values[known_idx[acc - 1]]

Осталась одна проблема: еслиначальное значение ниже -1.0 или выше -0.3, тогда все работает отлично.Но если он находится между ними, он будет зависеть от своего левого соседа, которого у него нет.Так что в вашем случае вы просто определяете его как ноль.

Мы можем сделать это, проверив, равняется ли acc[0] 0 или 1.Если acc[0] = 1, то все в порядке, но если acc[0] = 0, то это означает, что первое значение находится между -1.0 и -0.3, поэтому мы должны установить его на ноль:

if not acc[0]:
    result[0] = False
* 1053Наконец, поскольку мы много сравнивали, наш массив result является логическим массивом.Чтобы преобразовать его в целое число 0 и 1, мы просто вызываем
result = np.int8(result)

и получаем желаемый результат:

array([0, 1, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0], dtype=int8)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...