Построение только стабильных точек временного ряда и выполнение линейной регрессии

У меня есть два вопроса, которые я включил в один запрос на помощь. поэтому я надеюсь, что это не сделает его переполненным.

Я трачу довольно много времени на то, чтобы разобраться в этом, но пока безуспешно. Я пытаюсь построить только точки из ряда данных, которые близки друг к другу, а не переходы (см. график ниже). Вероятно, мне нужно условие if, которое говорит, что график x(2)-x(1)<0,005, а если нет, то не строит. Позже я хочу сделать линейную регрессию по этим точкам (поэтому я хочу исключить переходы). Не могли бы вы помочь мне, как построить график с этим условием и выполнить линейную регрессию.

Построение только стабильных точек временного ряда и выполнение линейной регрессии

Это мой код:


# which value you want to use or plot reading from log data
desired_field1= "x y Box"
desired_value1 = "x1 [um]"
desired_field2= "x y Box"
desired_value2 =  "x3 [um]"
desired_field3= "LM Position"
desired_value3 =  "Z [um]"


# extracting desired data from logging
data=pd.read_excel(r"test2.xlsx", sheet_name='Sheet1')
data = data[(data['_time'] < '2024-05-21T09:49:37.6089875Z') & (data['_time'] > '2024-05-21T09:43:31.7141954Z')] #selecting desired time interval
data_measurement1 = data.loc[data['_measurement'] == desired_field1]
data_field1 = data_measurement1.loc[data['_field'] == desired_value1]
data_measurement2 = data.loc[data['_measurement'] == desired_field2]
data_field2 = data_measurement2.loc[data['_field'] == desired_value2]
data_measurement3 = data.loc[data['_measurement'] == desired_field3]
data_field3 = data_measurement3.loc[data['_field'] == desired_value3]
values1 = list(data_field1['_value']) #values we are interested in
values2 = list(data_field2['_value'])
values3 = list(data_field3['_value'])
#....

mean_xs = [(g + h) / 2 for g, h in zip(values1, values2)]
LM_mean = [50-x for x in mean_xs]

#start plotting
data_field1['_time'] = pd.to_datetime(data_field1['_time'].str.split().str[-1])
data_field2['_time'] = pd.to_datetime(data_field2['_time'].str.split().str[-1])
data_field3['_time'] = pd.to_datetime(data_field3['_time'].str.split().str[-1])
plt.plot(data_field1['_time'], values1, '-', label = desired_value1)
plt.plot(data_field2['_time'], values2, '-', label = desired_value2 )
plt.plot(data_field3['_time'], values3, '-', label = desired_value3)


plt.xlabel('time [D hh:mm]')
plt.ylabel(' x [um] MCS')
plt.legend(loc='best')
plt.gca().yaxis.grid(True)

plt.figure()
plt.plot(LM_mean, values3, 'o')

пример данных:

9988   2024-05-21T09:46:00.1164445Z  1294.005333
9989   2024-05-21T09:46:01.1115275Z  1294.005333
9990   2024-05-21T09:46:02.1254956Z  1294.005667
9991   2024-05-21T09:46:03.1191685Z  1294.005667
9992   2024-05-21T09:46:04.1325494Z  1294.005333
9993   2024-05-21T09:46:05.1268794Z  1294.005333
9994   2024-05-21T09:46:06.1409297Z  1294.005333
9995   2024-05-21T09:46:07.1346292Z  1294.005000
9996   2024-05-21T09:46:08.1488069Z  1294.005333
9997   2024-05-21T09:46:09.1417524Z  1294.005333
9998   2024-05-21T09:46:10.1563002Z  1294.005333
9999   2024-05-21T09:46:11.1692835Z  1294.005333
10000  2024-05-21T09:46:12.1642492Z  1332.747333
10001  2024-05-21T09:46:13.1977216Z  1344.011333
10002  2024-05-21T09:46:14.1926256Z  1344.012000
10003  2024-05-21T09:46:15.2062685Z  1344.011667
10004  2024-05-21T09:46:16.2200463Z  1344.011667
10005  2024-05-21T09:46:17.2339343Z  1344.012000
10006  2024-05-21T09:46:18.2479639Z  1344.012000
10007  2024-05-21T09:46:19.2405515Z  1344.012000
10008  2024-05-21T09:46:20.2556817Z  1344.012000

Я пытался найти это, но безуспешно

Обновление о том, как я это решил, обратите внимание, что у меня есть два временных ряда, и я хотел построить их график друг против друга за один и тот же временной интервал:

idxSteps = np.array(np.where(np.abs(x.diff()) > 0.05)) 
idxSteps2 = np.array(np.where(np.abs(y.diff()) > 0.05))
previousStep = 0 # init the previous step
xIdx = list()
xMid = list() # init list for x
yMid = list() # ==/== for y
i=0
for currentStep in idxSteps[0]:# for every step detected
   if currentStep != previousStep:
           if currentStep in idxSteps2[0]:# and if they are not the same as previousStep
               dummyX = x[previousStep:currentStep] # get the data between these two steps
               dummyY = y[previousStep:currentStep] # ==/==
               xIdx.append((previousStep+currentStep)//2)
               xMid.append(dummyX.mean())
               yMid.append(dummyY.mean()) # append the statistical mode (most recurring value)
               previousStep = currentStep
               assign previousStep as currentStep for the next loop
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
0
0
104
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Извините, что заняло слишком много времени, надеюсь, что смогу помочь вам следующим исправленным ответом.

Вот код в виде дампа, я объясню код шаг за шагом в разделе после кода:

%matplotlib notebook
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
import matplotlib.dates as mdates 
df = pd.read_excel("Data.xlsx")
df["Datetime"] = pd.to_datetime(df["Datetime"])
idxSteps = np.array(np.where(np.abs(df["Data"].diff()) > 20)) # search for drops as the abs of the difference
previousStep = 0 # init the previous step
xIdx = list()
xMid = list() # init list for x
yMid = list() # ==/== for y
for currentStep in [idxSteps[0], len(df.index)]: # for every step detected
    if not isinstance(currentStep, int):
        currentStep= currentStep[0]
    if currentStep != previousStep: # and if they are not the same as previousStep
        dummyX = df["Datetime"].loc[previousStep:currentStep] # get the data between these two steps
        dummyY = df["Data"].loc[previousStep:currentStep] # ==/==
        xIdx.append((previousStep+currentStep)//2)
        xMid.append(dummyX.mean()) # append to the average of the date to the x list
        yMid.append(dummyY.mode()) # append the statistical mode (most recurring value)
        previousStep = currentStep # assign previousStep as currentStep for the next loop
plt.figure()
plt.plot(df["Datetime"], df["Data"])
plt.scatter(xMid, yMid, marker = "x", color = "red")
fit = np.polyfit(xIdx, yMid, 1) # fit
plt.plot(df["Datetime"], np.polyval(fit, df["Datetime"].index), "k--") # plot fit
locator = mdates.AutoDateLocator(minticks = 3, maxticks = 7)
formatter = mdates.ConciseDateFormatter(locator)
plt.gca().xaxis.set_major_locator(locator) 
plt.gca().xaxis.set_major_formatter(formatter) 
plt.grid()

Для начала я сохранил данные, которые вы включили в публикацию, в файл Excel со следующей структурой:

Я могу прочитать это с помощью функции pd.read_excel(), помня, что столбец datetime необходимо преобразовать с помощью pd.to_datetime()

Затем мы в основном делаем следующее:

  • вычислить производную данных для обнаружения скачков
  • получить участки между прыжками
  • вычислить индекс, дату и время и координаты y
  • Мы предполагаем, что данные начинаются и заканчиваются плоскими данными и, следовательно, начинаются с начала данных (previousStep = 0) и повторяются до последнего элемента в фрейме данных for currentStep in [idxSteps[0], len(df.index)]
  • После расчета того, что нам нужно, мы устанавливаем previousStep = currentStep, а затем цикл начинается снова.

Некоторая важная информация:

  1. Причина, по которой мы сохраняем индекс, заключается в том, что мы хотим использовать его для регрессии, поскольку регрессиям не нравятся форматы даты и времени.
  2. Чтобы получить координаты Y, я выбрал статистический режим: наиболее повторяющееся значение.
  3. Чтобы получить координаты x, я выбрал среднее значение сечения. Если вы хотите, чтобы координата x была определена в начале прыжка, используйте min(). Альтернативно, в конце используйте max()

Вот как выглядит конечный результат:

Примечание для вас: пожалуйста, прочитайте и поймите мой код. Не копируйте и не надейтесь на лучшее. Проверьте промежуточные данные, которые я генерирую с помощью кода.

Этот код пока работает только для того раздела данных, который вы опубликовали. На других это может не сработать, поэтому важно понимать, как было продумано это решение! Так что вы можете придумать собственное решение!

Привет, Тино, еще раз спасибо за твой ответ. Я не уверен, почему, когда я использую это для своих данных, xMid создается как NaN и имеет только два значения, в то время как я ожидаю, что по крайней мере массив длиной 50. Проблема с xMid, добавление создает данные NaN.

K S 28.05.2024 12:50

Есть ли в ваших данных наны? Кроме того, вы проверили, можно ли улучшить обнаружение прыжков? Как выглядит df["Data"].diff()?

Tino D 28.05.2024 12:53

да, я запускаю print(df["Data"].diff()) и он действительно показывает некоторые значения NaN.

K S 28.05.2024 13:03

Можете ли вы скопировать эту часть данных в вопрос?

Tino D 28.05.2024 13:10

Я исправил проблему NaN в diffvalues. Проблема заключается в этой части кода, который создает Nan для xMid.

K S 28.05.2024 13:16

эта часть: для currentStep в [idxSteps[0], len(df.index)]: .....

K S 28.05.2024 13:16

Эй, я могу помочь вам, насколько смогу, но боюсь, кое-что вам придется выяснить самостоятельно... без данных мне очень сложно (на самом деле невозможно) воспроизвести то, что вы видите

Tino D 28.05.2024 13:20

Я приложил к вопросу значения различий.

K S 28.05.2024 13:24

@KS Я не могу импортировать изображение как данные, и мне не нужны значения различий, мне нужны необработанные значения

Tino D 28.05.2024 13:29

Я отлаживал код и думаю, что это ненормально, что он показывает это значение для dummyX, когда я печатаю его на этапе, и после его вычисления просто печатаю это: Series([], Name: _time, dtype: object). так что похоже, что он не записывает данные между шагами

K S 28.05.2024 13:37

Я думаю, что мне не разрешено делиться здесь своими данными Excel. Поэтому не знаю, как поделиться необработанными данными.

K S 28.05.2024 13:39

По моему мнению, вам придется разобраться в этом самостоятельно. Трудно требовать конкретных ответов, не предоставляя конкретных данных. Что касается другого вопроса, который вы задали, это довольно легко, поскольку это общая проблема.

Tino D 28.05.2024 13:41

@KS, узнайте больше stackoverflow.com/questions/20109391/…

Tino D 28.05.2024 13:42

Другие вопросы по теме