Ваш вопрос не о питоне, а об обработке сигналов.
Есть много методов и проблем, связанных с оценкой фазы. Например, в периодических сигналах (таких как косинус или прямоугольная волна) есть бесконечные правильные ответы, поскольку реальный сдвиг фазы + целое число периодов даст тот же результат. С другой стороны, даже в непериодических сигналах, таких как один импульс, шум может влиять на обнаружение фазы, в некоторых случаях больше, чем в других. Это широкое поле, и ответ сильно зависит от того, чего вы хотите достичь, и качества данных.
Сказав это, вот мой вывод из ваших данных (двух компонентов) с использованием ACF в качестве первого шага для проверки, я не вижу проблемы с этим:
EDIT:
Добавлены некоторые исправления и изменены сигналы для реальных целей.
ДРУГОЕ РЕДАКТИРОВАНИЕ:
Что касается оценки фазового сдвига, есть много способов сделать это. Пожалуйста, изучите традиционную литературу для ответов и изучите методы, ориентированные на ваш тип данных. Мои предложения:
- Первый пик АКФ может быть хорошим ответом.
- Проекция на синусоидальные волны (частичные ряды Фурье) и корректировка фазы по наибольшим коэффициентам.
- Обнаружение фазы на основе подгонки тех же моделей и проверки параметров (может быть выполнено автоматически, зависит от модели).
- Использование детектора огибающей (для этих данных) и определения фаз между двумя верхними и двумя нижними линиями. Вы получите две оценки, вы можете взять среднее.
- Используйте больше предварительной обработки - разложение трендов и сезонности, а для проверки фазы берется компонент сезонности.
Есть много способов, они просто появляются сразу. Я уверен, что, немного поиграв с этим, вы сможете найти, что оно подходит вашим данным за разумное время вычислений, поэтому оно будет применимо для вашего продукта.
Удачи!



Вот код:
# 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()