计算两个信号之间的时移并进行平移

时间:2018-09-17 11:26:59

标签: python matplotlib

我有一个温度传感器和一个应变传感器,我想计算两个传感器之间的时间延迟。

def process_data_time_delay(temperature, strain, normal_data):
    from scipy import signal

    T1 = temperature['T1'].tolist()
    S1 = strain[0]
    time = normal_data['TIMESTAMP'].tolist()

    fig = plt.figure()
    plt.plot(time, T1, 'r')
    plt.plot(time, S1, 'b')

    shift = (np.argmax(signal.correlate(T1, S1)))
    fig  = plt.figure()
    plt.plot(time, T1 - shift)
    plt.show()

我有一个奇怪的输出图。

enter image description here

这是示例数据

https://pastebin.com/eEd6MTL0

根据出色的答案,我修改了代码以计算两个信号之间的时间延迟。

def process_data_time_delay(temperature, strain, df):
    from scipy import signal

    # normalization before ACF
    def normalize(data):
        return (data - np.mean(data, axis=0).reshape((1, -11))) / (np.std(data, axis=0).reshape((1, -1)))

    # select subset of columns, seems relevant as a group
    SCOLS = ['T1', 'W_A1']

    # just to see the data
    f = plt.figure()
    ax = f.add_subplot(111)
    df[SCOLS[:2]].iloc[::10].plot(ax=ax)
    ax.set_title('Raw data')

    # normalization
    normalized = normalize(df[SCOLS].values)
    f = plt.figure()
    ax = f.add_subplot(111)
    ax.plot(np.arange(normalized.shape[0]), normalized[:, 0], label='TW_A1')
    ax.plot(np.arange(normalized.shape[0]), normalized[:, 1], label='W_A1')
    ax.set_title('Normalized')

    # ACF between two components
    x1x2 = np.correlate(normalized[:, 0], normalized[:, 1], 'full')

    # see the results
    f = plt.figure()
    ax = f.add_subplot(111)
    ax.plot(x1x2)
    ax.set_title('ACF')
    df['TIMESTAMP'] = pd.to_datetime(df['TIMESTAMP'])
    peaks_indices = signal.find_peaks_cwt(np.array(x1x2), np.arange(1, len(x1x2)))
    print(peaks_indices)
    delta_index = np.argmax(peaks_indices);
    delta_time = df['TIMESTAMP'][delta_index] - df['TIMESTAMP'][0]
    # assuming timestamps is a datetime64 numpy array that can be easily obtained from pandas;
    shifted_signal = x1x2[delta_time:]

    f = plt.figure()
    ax = f.add_subplot(111)
    ax.plot(shifted_signal)

    # mainloop
    plt.show()

    return x1x2

1 个答案:

答案 0 :(得分:1)

您的问题不是关于python,而是关于信号处理。 相位估计有很多技术和问题。例如,在周期信号(例如余弦或方波)中,存在无限正确的答案,因为实际相移+周期的整数倍将得出相同的结果。另一方面,即使在非周期性信号(例如一个脉冲)中,噪声也可能影响相位检测,在某些情况下,其影响要大于其他情况。该领域广阔,答案很大程度上取决于您要实现的目标和数据质量。

话虽如此,这是我使用ACF作为检查的第一步的数据(两个组件)的输出,我认为没有问题:

编辑:
添加了一些更正,并更改了真实目标的信号。

另一项编辑:

关于相移估计,有许多方法可以做到。请研究传统文献以寻找答案,并探索适合您数据类型的技术。我的建议:

  1. ACF的第一个高峰可能是一个很好的答案。
  2. 投影正弦波(部分傅里叶级数)并以最大系数调整相位。
  3. 基于拟合相同模型和参数检查的相位检测(可以自动完成,具体取决于模型)。
  4. 使用包络检测器(用于此数据)并检测上两条线和两条下线之间的相位。您将获得两个估计值,可以取平均值。
  5. 使用更多的预处理-趋势和季节性分解,并使用季节性成分检查阶段。

有很多方法,这些方法会立即弹出。我敢肯定,只要稍加操作,您就能在合理的计算时间内找到适合您数据的数据,从而将其应用于您的产品。

祝你好运!

enter image description here

enter image description here

enter image description here

代码如下:

# just some imports
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt

plt.style.use('ggplot')

# load data
df = pd.read_csv('c:\\Temp\\curve_fitting_ahmed.csv')

# normalization before ACF
def normalize(data):
    return (data - np.mean(data, axis=0).reshape((1, -11))) / (np.std(data, axis=0).reshape((1, -1)))


# select subset of columns, seems relevant as a group
SCOLS = ['TW_A1','W_A1']

# just to see the data
f = plt.figure()
ax = f.add_subplot(111)
df[SCOLS[:2]].iloc[::10].plot(ax=ax)
ax.set_title('Raw data')

# normalization
normalized = normalize(df[SCOLS].values)
f = plt.figure()
ax = f.add_subplot(111)
ax.plot(np.arange(normalized.shape[0]),normalized[:,0], label='TW_A1')
ax.plot(np.arange(normalized.shape[0]),normalized[:,1], label='W_A1')
ax.set_title('Normalized')

# ACF between two components
x1x2 = np.correlate(normalized[:, 0], normalized[:, 1], 'full')

# see the results
f = plt.figure()
ax = f.add_subplot(111)
ax.plot(x1x2)
ax.set_title('ACF')

# mainloop
plt.show()