Python信号计数器

时间:2016-11-18 18:33:57

标签: python signals analysis

我从实验中获取了两个数据阵列; x(时间)和y(电压)。这些绘制如下。每隔200微秒,信号就是三种状态之一:

  1. 取负值(即<-0.25 V)
  2. 取正值(即> 0.3 V)
  3. 保持在噪音水平(即〜在0和0.1 V之间)
  4. x,y plotted

    我想数字化&#39;这个信号,所以情况1.,2。和3.,对应于-1,+ 1或0的离散值。

    如何通过分析数据数组来做到最好?

    我目前的想法:

    • 进行插值以找到y值满足每个阈值的x值。

    np.interp(0.5,x,y)

    问题:

    • 如何满足y阈值的多个位置?

4 个答案:

答案 0 :(得分:2)

对于N个阈值,有N + 1个等级。使用以下步骤找到平交道口:

  • 遍历所有样本,然后是阈值,
  • 通过比较绝对值组合的乘积来检查当前水平和样本的交叉点,例如: abs(y1)* y0!= y1 * abs(y0)。< / LI>
  • 如果发生了平交道口,则使用线性方程找到交叉点的x值。
  • 斜率的极性告诉您交叉是否来自低于或高于的水平,表示当前水平。

以下函数实现了上述内容:

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

以下输入用于测试功能:

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

此函数返回的级别是无符号的,从零开始,因此函数的结果向下移一:

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

结果如下:

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

答案 1 :(得分:0)

假设您的数据位于pandas数据表(dataxy)中,我会先清理一下数据(数字化)。

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我会通过计算后续元素之间的差异来检查斜率

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

现在贯穿你的差异并计算

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

答案 2 :(得分:0)

作为解决方案之一,您可以使用所需的值替换它们:

 >>> 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.])
 >>>

答案 3 :(得分:0)

您可以通过执行my_array > 0.3之类的检查来对数据进行离散化,这样可以返回一个可以转换为1和0的布尔数组:np.array( my_array > 0.3 ,int)

通过从信号中减去移位信号(插入信号的第一个元素的副本)可以找到跳跃的位置:

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

我在一些看起来与你的相似的随机信号上测试了这个:

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

返回跳转发生的次数(带有新值的第一个元素)和信号跳转到的值(+ 1,0,-1)。