2015-07-09 2 views
0

У меня есть некоторые формы сигнала, которые я пытаюсь обрабатывать с помощью Python. Я хотел бы найти дискретные уровни логики, отображаемые этими сигналами. У меня есть 1D-массив значений x и y каждой формы сигнала.Поиск дискретных логических уровней в форме волны

данные выглядит примерно так, например, лестница:

example

Как я могу найти различные уровни? Здесь они могут быть вокруг (1,8, 3,3), (2,1, 3,0), (2,7, 2,6) и т. Д.

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

+0

Я буду идти вперед и удалить R тег, поскольку он не имеет отношения к вашей проблеме программирования. – Frank

ответ

0

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

import numpy as np 
import matplotlib.pyplot as plt 
from scipy.signal import argrelmin, argrelmax 

#Generate some example signal 
res = 1000 
x = np.linspace(0,2*np.pi,res) 
y = np.sin(x) 
plt.plot(x,y) 

#Take a number of discrete steps 
Nsteps = 10 
skip = x.shape[0]/Nsteps 
xstep = x[::skip]; ystep = y[::skip] 
plt.plot(xstep,ystep,'o') 

#Plot the step graph 
plt.step(xstep, ystep) 

#Get max and min (only 2 in this simple case) 
plt.plot(x[argrelmax(y)[0]],y[argrelmax(y)[0]],'ro') 
plt.plot(x[argrelmin(y)[0]],y[argrelmin(y)[0]],'ro') 
plt.show() 

который дает

enter image description here

Для более сложного решения в ссылке, я подумайте, что это будет связано со строительством ystep путем поиска местного минимума/максимума в заданном диапазоне, например:

ystep =[] 
for rec in range(0,x.shape[0],skip): 
    ystep.append(y[argrelmax(y[rec:rec+skip])[0]]) 

EDIT: полный пример дает локальную мин/макс для диапазона

import numpy as np 
import matplotlib.pyplot as plt 
from scipy.signal import argrelmin, argrelmax 

#Generate some example signal 
res = 1000 
x = np.linspace(0,2*np.pi,res) 
y = np.sin(x) 
plt.plot(x,y) 

#Take a number of discrete steps 
Nsteps = 10 
skip = x.shape[0]/Nsteps 

#Get local minimum and maximum in blocks for whole set of data 
xstep = []; ystep =[] 
for rec in range(0,x.shape[0],skip): 
    srt = rec 
    end = rec+skip-1 
    if (y[srt] > y[end]): 
     indx = argrelmax(y[srt:end],mode='wrap')[0] 
    elif (y[srt] < y[end]): 
     indx = argrelmin(y[srt:end],mode='wrap')[0] 

    xstep.append(x[srt+indx]) 
    ystep.append(y[srt+indx]) 

#Plot location of min/max 
plt.plot(xstep,ystep,'o') 

#Plot the step graph 
plt.step(xstep, ystep) 

plt.show() 
+0

Мне нравится полное редактирование. Я вижу, что это используется с катящимся окном через функцию с помощью Nsteps = 1, чтобы продолжать корректировать этот единственный макс и возвращать каждое значение, которое делает значительный скачок, Таким образом, если есть многоуровневый сигнал, вы можете найти множественные максимумы/уровни, которые представлены. – moseyic

+0

Да, извините, я бросил оригинальный ответ и не думаю, что этого будет достаточно для более сложных случаев в вашей связи «R». Вам нужно 'mode =" wrap ", поэтому он принимает периодический сигнал и находит экстерм диапазона с обоих концов. Если есть более одного мин/макс, вам также может потребоваться изменить это немного, так как 'indx' будет массивом. Вы можете использовать 'argrelextrema', чтобы избежать инструкций' if'. –

+0

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