Python pandas интерполяция временных рядов и регуляризация

Я использую Python Pandas в первый раз. У меня есть 5-минутные данные трафика задержки в формате csv:

...
2015-01-04 08:29:05,271238
2015-01-04 08:34:05,329285
2015-01-04 08:39:05,-1
2015-01-04 08:44:05,260260
2015-01-04 08:49:05,263711
...

Есть несколько проблем:

  • для некоторых временных меток отсутствуют данные (-1)
  • отсутствующие записи (также 2/3 последовательных часа)
  • частота наблюдений не составляет ровно 5 минут, но на самом деле теряет несколько секунд раз в то время

Я хотел бы получить регулярные временные ряды, поэтому с записями каждые (ровно) 5 минут (и без пропущенных значений). Я успешно интерполировал временные ряды со следующим кодом для приближения значений -1 с помощью этого кода:

ts = pd.TimeSeries(values, index=timestamps)
ts.interpolate(method='cubic', downcast='infer')

Как я могу интерполировать и упорядочить частоту наблюдений? Спасибо всем за помощь.

Ответ 1

Измените -1 на NaNs:

ts[ts==-1] = np.nan

Затем пересчитайте данные, чтобы иметь 5-минутную частоту.

ts = ts.resample('5T')

Обратите внимание, что по умолчанию, если два измерения попадают в тот же 5-минутный период, resample усредняет значения вместе.

Наконец, вы можете линейно интерполировать временные ряды по времени:

ts = ts.interpolate(method='time')

Так как похоже, что ваши данные уже имеют примерно 5-минутную частоту, вы может потребоваться повторная выборка с более короткой частотой, так что кубическая или сплайн-интерполяция может сгладить кривую:

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt

values = [271238, 329285, -1, 260260, 263711]
timestamps = pd.to_datetime(['2015-01-04 08:29:05',
                             '2015-01-04 08:34:05',
                             '2015-01-04 08:39:05',
                             '2015-01-04 08:44:05',
                             '2015-01-04 08:49:05'])

ts = pd.Series(values, index=timestamps)
ts[ts==-1] = np.nan
ts = ts.resample('T', how='mean')

ts.interpolate(method='spline', order=3).plot()
ts.interpolate(method='time').plot()
lines, labels = plt.gca().get_legend_handles_labels()
labels = ['spline', 'time']
plt.legend(lines, labels, loc='best')
plt.show()

enter image description here