2016-11-18 50 views
5

Mam dwie tablice danych pobranych z eksperymentu; x (czas) i y (napięcie). Są one przedstawione poniżej. Co 200 mikrosekund, sygnał jest jednym z trzech stanów:Licznik sygnałów w języku Python

  1. przyjmować wartość ujemną (tj < -0,25 V)
  2. Take wartość dodatnią (czyli> 0,3 V)
  3. Pozostają na poziomie hałas (np ~ między 0 i 0,1 V)

x,y plotted

Chciałbym 'digitalizacji' tego sygnału, tak, że Przypadek 1, 2 i 3 ., odpowiadają dyskretnym wartościom -1, +1 lub 0.

Jak to zrobić najlepiej, analizując tablice danych?

Mój obecny pomysł:

  • interpolować znaleźć wartości x, gdzie y spotykać próg.

np.interp(0.5,x,y)

Problem:

  • Jak to na wielu pozycjach, gdzie próg y jest spełniony?
+0

Wygląda na to, że rozwiązanie jest już uporządkowane; wystarczy, że przekręcisz skrzynie, by kodować bezpośrednio. Czy masz jakiś inny problem z ustaleniem progu? –

+0

Już znasz zachowanie, które chcesz, więc możesz po prostu napisać funkcję, która implementuje to zachowanie i mapuje je na twoje dane? – user3030010

+0

Wspominam, że nie jestem pewien, jak to zrobić, aby policzyć wszystkie pozycje w śladzie, w których próg jest spełniony, a nie tylko pierwszy przypadek, który 'np.interp()' zwraca – 8765674

Odpowiedz

0

Zakładając, że nasze dane w DataTable Pandy (data z kolumnami x i y), chciałbym najpierw oczyścić swoje dane trochę (digitalizacją go).

data.loc[data['y'] > 0.3, 'y'] = +1 
data.loc[data['y'] < -0.25, 'y'] = -1 
data.loc[(data['y'] >= -0.25) & (data['y'] <= 0.3), 'y'] = 0 

Afterwars chciałbym sprawdzić nachylenie poprzez obliczenie różnicy między elementami supsequent

data_diff = data.set_index('x').diff(periods=1, axis=0) 

Teraz prowadzony przez swoje różnice i liczyć

state = 0 
pos_peaks = 0 
neg_peaks = 0 
flats = 0 
for row in data_diff.itertuples(): 
    if row[1] > 0 and state == 0: 
     pos_peaks += 1 
     state = 1 
    elif row[1] < 0 and state == 0: 
     neg_peaks +=1 
     state = -1 
    elif row[1] < 0 and state == 1: 
     flats += 1 
     state = 0 
    elif row[1] > 0 and state == -1: 
     flats += 1 
     state = 0 
+0

Nie używając pand. Jaki jest cel '.diff'? – 8765674

+0

'.diff()' jest funkcją w pandach, która oblicza różnicę wzdłuż osi. W tym przypadku oblicza różnicę między kolejnymi wierszami. patrz http://stackoverflow.com/a/13115473/4141279 – RaJa

0

Jako jedno z rozwiązań, można je zastąpić z wymaganymi wartościami:

>>> a=np.random.rand(10)-0.5 # just for test 
>>> a 
array([-0.16532652, 0.17079655, -0.08183734, -0.42446642, -0.15749626, 
     0.31809266, 0.09871911, 0.10324168, 0.43021048, 0.16749866]) 
>>> a[a<-0.3] = -1 
>>> a[a>0.25] = +1 
>>> a 
array([-0.16532652, 0.17079655, -0.08183734, -1.  , -0.15749626, 
     1.  , 0.09871911, 0.10324168, 1.  , 0.16749866]) 
>>> a[(a>-1) & (a<1)]=0 
>>> a 
array([ 0., 0., 0., -1., 0., 1., 0., 0., 1., 0.]) 
>>> 
2

Dla progów N występuje poziom N + 1. przejazdy stwierdzono za pomocą następujących czynności:

  • iterację wszystkich próbkach, a następnie wartości progowych
  • Sprawdź aktualny poziom i próbki do przejścia przez porównanie produktów kombinacji wartości bezwzględne, np : abs (y1) * y0! = Y1 * abs (y0).
  • Jeśli doszło do przekroczenia poziomu, wartość x przecięcia znajduje się za pomocą równania liniowego.
  • Polaryzacja nachylenia informuje, czy przejście pochodziło z poziomu poniżej lub powyżej, wskazując aktualny poziom.

Następujące funkcje realizuje się powyżej

def quantizer(time,voltage,thresholds): 
    x0=time[0]; y0=voltage[0]; 
    l0 = 0 
    for level,thresh in enumerate(thresholds): 
     l0 = level if y0>thresh else l0 
    xings=[tuple([x0,l0])] 
    for x1,y1 in zip(time[1:],voltage[1:]): 
     xings_i=[] 
     dy=y1-y0 
     dx=x1-x0 
     dy_dx = dy/dx 
     for level,thresh in enumerate(thresholds): 
      y1s=y1-thresh 
      y0s=y0-thresh 
      if dy!=0: 
       if abs(y1s)*y0s!=y1s*abs(y0s): 
        xings_i.append(tuple([x0-y0s/dy_dx,level+1*(dy_dx>0)])) 
     xings_i.sort(key=lambda tup: tup[0]) 
     xings+=xings_i 
     x0=x1 
     y0=y1 
    return xings 

następujące komponenty były stosowane do testowania funkcji:

time = [ 0, 1, 2, 3, 4 ] 
voltage = [-2.0,-1.2, 2.0, 1.1,-4.0] 
thresholds = [-0.25,0.3] 

Poziomy powrotu tej funkcji są podpisane i rozpocząć od zera więc wynik funkcji jest przesunięty w dół o jeden:

def main(): 
    for t,level in quantizer(time,voltage,thresholds): 
     print(str(round(t,2)) + "\t" + str(level-1)) 

Wyniki wyglądają następująco:

0  -1 
1.3  0 
1.47 1 
3.16 0 
3.26 -1 
0

Można discretize dane wykonując kontrole jak my_array > 0.3, która zwraca tablicę logiczną które mogą być włączane do 1 i 0: np.array(my_array > 0.3 ,int).

Pozycje skoków można znaleźć poprzez odjęcie przesunięty sygnał (wstawianie kopię pierwszego elementu sygnału) z sygnału:

def jump(time,signal): 
    d_signal  = np.array(signal>.3,int) -np.array(signal<-.25,int) 
    shift   = d_signal - np.insert(d_signal,0,d_signal[0])[:-1] 
    time_of_jump = time[shift!=0] 
    jump_to_value = d_signal[shift!=0] 

    return time_of_jump,jump_to_value 

Sprawdzałem to na jakimś losowym sygnałem wygląda nieco podobny do Ciebie:

import numpy as np 
import matplotlib.pyplot as plt 

jumps=np.around(np.random.rand(30)*2-1)*.5 
signal=np.array([]) 

for i in jumps: 
    signal=np.hstack((signal , np.ones(10)*i + np.random.normal(0,.05,10))) 
time=np.arange(0,len(signal))*.01+239 

print(jump(time,signal)) # Python 3 
print jump(time,signal) # Python 2 

Zwraca tablicę czasów miały miejsce skoki (pierwszy element z nową wartość) i wartości (+ 1,0, -1), do którego wskoczył sygnał .