Найдите отметку времени, после которой набор данных становится монотонным

У меня есть фрейм данных, который содержит столбец высоты. Вначале высота остается неизменной с точки зрения колебаний сигнала GPS. В какой-то момент высота меняется, когда GPS-приемник перемещается во время подъема в гору. Как мне найти временную метку, когда высота начнет непрерывно перемещаться вверх? Простое сравнение «больше чем» не сработает, поскольку вначале во время разминки высота немного подпрыгивает.

Пример таймера здесь:

import pandas as pd
import numpy as np
 
df_GPS = pd.DataFrame([['2024-06-21 06:22:38', 605.968389],
                     ['2024-06-21 06:22:39', 606.009398],
                     ['2024-06-21 06:22:40', 605.630573],
                     ['2024-06-21 06:22:41', 605.476367 ],
                     ['2024-06-21 06:22:42', 605.322161],
                     ['2024-06-21 06:22:43', 605.268389],
                     ['2024-06-21 06:22:44', 605.559398],
                     ['2024-06-21 06:22:45', 606.630573],
                     ['2024-06-21 06:22:46', 607.476367 ],
                     ['2024-06-21 06:22:47', 609.322161],
                    ], columns=['time', 'Altitude'])

В идеале я бы получил в результате: время = 2024-06-21 06:22:43 так как оттуда высота монотонно возрастает.

Мой код все еще неисправен

start_move = df_GPS.loc[df_GPS['Altitude'] == df_GPS["Altitude"].is_monotonic_increasing, 'time'] 
print(start_move)    

Где моя опечатка?

🤔 А знаете ли вы, что...
С Python можно создавать веб-скраперы для извлечения данных из веб-сайтов.


55
1

Ответ:

Решено

Предполагая, что time преобразован в datatime/timestamp, вы можете просто посмотреть назад с конца, чтобы найти изменение от монотонного. Предполагая, что данные времени необходимо отсортировать, сначала измените порядок:

df_GPS_rev = df_GPS.sort_values(by = 'time', ascending = False)

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

df_GPS_rev = df_GPS.reindex(index = df_GPS.index[::-1])

затем

start_move = df_GPS_rev[df_GPS_rev['Altitude'] < df_GPS_rev['Altitude'].shift(-1)].iloc[0]

print(start_move['time'])

дает:

2024-06-21 06:22:43

Если (как позже определено в комментариях OP) данные НЕ всегда монотонно увеличиваются, а, например, уменьшаются в конце, то можно проверить скользящие окна на предмет монотонного увеличения:

# define window size
win= 3

# find windows which are monotonic increasing
df_GPS['win_inc'] = df_GPS.rolling(win)['Altitude'].apply(lambda x: x.is_monotonic_increasing)

#get index of end of first increasing window
idx = df_GPS[df_GPS['win_inc'].eq(True)].index[0]

# get time at start of first increasing window
start_move = df_GPS.loc[idx-win+1, 'time']
print(start_move)

что снова дает:

2024-06-21 06:22:43

Более быстрый, но менее лаконичный подход может использовать Numpy:

# define window size
win= 3
#create numpy array
alt = df_GPS['Altitude'].to_numpy()

#search through np array looking for first increasing window
start_idx = None
for idx, val in enumerate(alt[:1-win]):
    if np.all(np.diff(alt[idx:idx+win]) > 0):
        start_idx = idx
        break

if start_idx is not None:
    start_move = df_GPS.loc[start_idx, 'time']
    print(start_move)
else:
    print('no increasing windows')

что снова дает тот же результат