Нахождение локальных максимумов / минимумов с помощью Numpy в одномерном массиве Numpy
Можете ли вы предложить функцию модуля из numpy/scipy, которая может найти локальные максимумы/минимумы в массиве 1D numpy? Очевидно, что самый простой подход — это взглянуть на ближайших соседей, но я хотел бы иметь принятое решение, которое является частью дистрибутива numpy.
Нет, это в 2D (я говорю о 1D) и включает в себя пользовательские функции. У меня есть своя собственная простая реализация, но мне было интересно, есть ли лучшая реализация, которая поставляется с модулями Numpy / Scipy.
Возможно, вы могли бы обновить вопрос, включив в него: (1) у вас есть массив 1d и (2) какой локальный минимум вы ищете. Просто запись меньше, чем две соседние записи?
9 ответов
Если вы ищете все записи в массиве 1d a меньше, чем их соседи, вы можете попробовать
Вы также можете smooth ваш массив до этого шага с помощью numpy.convolve() .
Я не думаю, что для этого есть специальная функция.
Хм, а зачем мне сглаживать? Убрать шум? Это звучит интересно. Мне кажется, что я мог бы использовать другое целое число вместо 1 в вашем примере кода. Я также думал о расчете градиентов. Во всяком случае, если нет функции, то это очень плохо.
@Navi: Проблема в том, что понятие «локальный минимум» сильно варьируется от варианта использования к сценарию, поэтому сложно обеспечить «стандартную» функцию для этой цели. Сглаживание помогает учитывать не только ближайшего соседа. Использование другого целого числа вместо 1, скажем, 3, было бы странно, так как он рассматривал бы только третий элемент в обоих направлениях, но не прямые соседние элементы.
Я имел в виду рассмотрение количества соседей в обоих направлениях. Так что min (x) = min (x [i — n]: x [i + n]).
Хотя мне нравится решение Scipy, предоставляемое @danodonovan, этот метод кажется намного быстрее для больших наборов данных.
@Sven Свен Марнах: рецепт, на который вы ссылаетесь, задерживает сигнал. есть второй рецепт, который использует фильтрат от scipy.signal
@bobrobbob Вы можете удалить задержку, сократив расширения сигнала наполовину: s=np.r_[x[int(window_len/2):0:-1],x,x[-2:-int(window_len/2)-2:-1]]
import numpy as np from scipy.signal import argrelextrema x = np.random.random(12) # for local maxima argrelextrema(x, np.greater) # for local minima argrelextrema(x, np.less)
>>> x array([ 0.56660112, 0.76309473, 0.69597908, 0.38260156, 0.24346445, 0.56021785, 0.24109326, 0.41884061, 0.35461957, 0.54398472, 0.59572658, 0.92377974]) >>> argrelextrema(x, np.greater) (array([1, 5, 7]),) >>> argrelextrema(x, np.less) (array([4, 6, 8]),)
Обратите внимание, что это индексы x, которые являются локальными max/min. Чтобы получить значения, попробуйте:
>>> x[argrelextrema(x, np.greater)[0]]
scipy.signal также обеспечивает argrelmax и argrelmin для нахождения максимумов и минимумов соответственно.
@marshmallow: np.random.random(12) генерирует 12 случайных значений, они используются для демонстрации функции argrelextrema .
если входное значение test02=np.array([10,4,4,4,5,6,7,6]) , то оно не работает. Он не распознает последовательные значения как локальные минимумы.
@Leos313: Leos313: Вы можете использовать find_peaks (см. Мой ответ здесь ): find_peaks(test02) вернет (array([6]), <>) и find_peaks(-1*test02) вернет (array([2]), <>) , так что 4 определяется как локальный минимум.
спасибо, @Cleb. Я хочу указать на другие проблемы: как насчет крайних точек массива? первый элемент также является локальным максимумом, так как последний элемент массива также является локальным минимумом. И также, это не возвращает, сколько последовательных ценностей основано. Однако я предложил решение в коде этого вопроса здесь . Спасибо!!
Для кривых с не слишком большим шумом я рекомендую следующий небольшой фрагмент кода:
from numpy import * # example data with some peaks: x = linspace(0,4,1e3) data = .2*sin(10*x)+ exp(-abs(2-x)**2) # that the line, you need: a = diff(sign(diff(data))).nonzero()[0] + 1 # local min+max b = (diff(sign(diff(data))) > 0).nonzero()[0] + 1 # local min c = (diff(sign(diff(data))) < 0).nonzero()[0] + 1 # local max # graphical output. from pylab import * plot(x,data) plot(x[b], data[b], "o", label="min") plot(x[c], data[c], "o", label="max") legend() show()
+1 важен, поскольку diff уменьшает исходный номер индекса.
хорошее использование вложенных функций numpy! но обратите внимание, что это пропускает максимумы на любом конце массива 🙂
Это также будет действовать странно, если есть повторяющиеся значения. например, если вы возьмете массив [1, 2, 2, 3, 3, 3, 2, 2, 1] , локальные максимумы, очевидно, находятся где-то между 3-мя в середине. Но если вы запускаете функции, которые вы предоставили, вы получаете максимумы с индексами 2,6 и минимы с индексами 1,3,5,7, что для меня не имеет особого смысла.
Я знаю, что этой ветке уже много лет, но стоит добавить, что если ваша кривая слишком шумная, вы всегда можете сначала попробовать фильтрацию нижних частот для сглаживания. Для меня, по крайней мере, большинство моих локальных значений макс / мин используется для глобального макс / мин в некоторой локальной области (например, большие пики и впадины, а не каждое изменение данных)
Другой подход (больше слов, меньше кода), который может помочь:
Расположение локальных максимумов и минимумов также является местом пересечения нуля первой производной. Как правило, гораздо легче найти пересечения нуля, чем непосредственно находить локальные максимумы и минимумы.
К сожалению, первая производная имеет тенденцию "усиливать" шум, поэтому, когда в исходных данных присутствует значительный шум, первая производная лучше всего использовать только после того, как исходные данные имеют некоторую степень сглаживания.
Поскольку сглаживание в простейшем смысле является фильтром нижних частот, сглаживание часто лучше всего (ну, что наиболее легко) выполняется с использованием ядра свертки, и "формирование" этого ядра может обеспечить удивительное количество сохраняющих функцию/повышение возможностей. Процесс нахождения оптимального ядра может быть автоматизирован с использованием различных средств, но лучшим может быть простая грубая сила (достаточно много для поиска небольших ядер). Хорошее ядро будет (как и предполагалось) массивно искажать исходные данные, но не будет влиять на местоположение интересующих вас пиков/долин.
К счастью, довольно часто подходящее ядро может быть создано с помощью простого SWAG ( "образованное предположение" ). Ширина сглаживающего ядра должна быть немного шире, чем самый ожидаемый "интересный" пик в исходных данных, и его форма будет напоминать этот пик (одномасштабный вейвлет). Для ядер, сохраняющих среднее значение (каким должен быть любой хороший сглаживающий фильтр) сумма элементов ядра должна быть точно равна 1.00, а ядро должно быть симметричным относительно своего центра (что означает, что у него будет нечетное число элементов.
Учитывая оптимальное сглаживающее ядро (или небольшое количество ядер, оптимизированных для различного содержимого данных), степень сглаживания становится фактором масштабирования для ( "усиления" ) ядра свертки.
Определение "правильной" (оптимальной) степени сглаживания (усиление ядра свертки) может быть даже автоматизировано: сравните стандартное отклонение данных первой производной со стандартным отклонением сглаженных данных. Как отношение двух стандартных отклонений изменяется с изменением степени сглаживания кулачка, чтобы предсказать эффективные значения сглаживания. Необходимо выполнить несколько ручных операций с данными (которые действительно являются репрезентативными).
Все предыдущие решения, вышеперечисленные выше, вычисляют первую производную, но они не рассматривают ее как статистическую меру и не выполняют вышеуказанные решения для выполнения функции сохранения/улучшения сглаживания (чтобы помочь тонким пикам "прыгать выше" шума).
Наконец, плохая новость: поиск "реальных" пиков становится королевской болью, когда шум также имеет функции, которые выглядят как реальные пики (перекрывающиеся полосы пропускания). Следующее более комплексное решение, как правило, должно использовать более длинное сверточное ядро ( "более широкую апертуру ядра" ), которое учитывает взаимосвязь между смежными "реальными" пиками (такими как минимальные или максимальные скорости для возникновения пика) или использовать множественные свертки передаются с использованием ядер разной ширины (но только в том случае, если они быстрее: фундаментальная математическая истина состоит в том, что линейные свертки, выполняемые в последовательности, всегда могут быть свернуты вместе в одну свертку). Но часто гораздо легче сначала найти последовательность полезных ядер (различной ширины) и свернуть их вместе, чем напрямую находить последнее ядро за один шаг.
Надеемся, это даст достаточно информации, чтобы позволить Google (и, возможно, хороший текст статистики) заполнить пробелы. Мне очень жаль, что у меня не было времени предоставить обработанный пример или ссылку на него. Если кто-то наткнулся на один онлайн, отправьте его здесь!
Написать программу поиска всех локальных минимумов и максимумов в списке
Есть список целыми положительными числами, лежащими в диапазоне от 0 до 50 включительно. Написать программу поиска всех локальных
минимумов и максимумов в списке (элемент называется локальным
минимумом/максимумом, если у него нет соседей, которые меньше/больше его).
Построить массив, в котором a локальных минимумов и b локальных максимумов.
Может кто-нибудь дать подсказку по задаче? Никак не могу найти решение Условие: Рассмотрим.
Количество локальных максимумов/минимумов
Как подсчитать количество локальных максимумов/минимумов в массиве? Не получается никак import.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
from random import randint a = [] minim = [] maxim = [] n = int(input('Введите длину списка: ')) for i in range(n): a.append(randint(0, 50)) print(a) for i in range(1, n - 1): if a[i] a[i + 1] and a[i] a[i - 1]: minim.append(a[i]) if a[i] > a[i + 1] and a[i] > a[i - 1]: maxim.append(a[i]) if len(minim) == 0: print('Локальных минимумов нет') else: print('Локальные минимумы:', minim) if len(maxim) == 0: print('Локальных максимумов нет') else: print('Локальные максимумы: ', maxim)
Создать программу поиска локальных максимумов функции на интервале наблюдения
Всем привет. Подскажите с чего начать. Какую функцию мне брать? Создать программу поиска локальных.
Найти количество локальных минимумов и максимумов массива
Дан массив размера N. Найти количество его локальных минимумов1|максимумов2.
Найти количество локальных минимумов/максимумов массива
Задание: написать программу, реализующую следующие задания, и реализовать ее графический интерфейс.
Найдите точки локальных минимумов и точки локальных максимумов функции
Помогите пожалуйста найти точки локальных минимумов и точки локальных максимумов функции.
Разработать шаблонный класс для нахождения локальных максимумов и минимумов в массиве
Помогите пожалуйста. Необходимо найти количество абсолютных и локальных минимумов и максимумов.
Найдите количество абсолютных и локальных минимумов и максимумов среди элементов одномерного массива
Найдите количество абсолютных и локальных минимумов и максимумов среди элементов одномерного.