问题描述
我有一个温度传感器和一个应变传感器,我想计算两个传感器之间的时间延迟。
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()
我有一个奇怪的输出图。
这是一个示例数据
根据出色的答案,我修改了代码以计算两个信号之间的时间延迟。
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楼
您的问题不是关于python,而是关于信号处理。 相位估计有很多技术和问题。 例如,在周期信号(例如余弦或方波)中,存在无限正确的答案,因为实际相移+周期的整数倍将得出相同的结果。 另一方面,即使在非周期性信号(例如一个脉冲)中,噪声也可能影响相位检测,在某些情况下,其影响要大于其他情况。 这个领域很广泛,答案很大程度上取决于您要实现的目标和数据质量。
话虽如此,这是我使用ACF作为检查的第一步的数据(两个组件)的输出,我认为没有问题:
编辑:
添加了一些更正,并更改了真实目标的信号。
另一个编辑:
关于相移估计,有很多方法可以做到。 请研究传统文献以寻找答案,并探索适合您数据类型的技术。 我的建议:
- ACF的第一个高峰可能是一个很好的答案。
- 投影正弦波(部分傅立叶级数),并以最大系数调整相位。
- 相位检测基于拟合相同的模型并检查参数(可以自动完成,具体取决于模型)。
- 使用包络检波器(用于此数据)并检测两个上线和两个下线之间的相位。 您将获得两个估计值,可以取平均值。
- 使用更多的预处理-趋势和季节性分解,并使用季节性部分检查阶段。
有很多方法,这些方法会立即弹出。 我敢肯定,只要稍微花一点时间,您就可以在合理的计算时间内找到适合您数据的数据,从而将其应用于您的产品。
祝好运!
这是代码:
# 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()