Pandas: Интерполировать (upsample) временные ряды с неравномерным интервалом в равномерный интервал 18.0rc1

Созданный на 7 мар. 2016  ·  3Комментарии  ·  Источник: pandas-dev/pandas

Я хочу интерполировать (масштабировать) временные ряды без интервалов, чтобы получить временные ряды с равными интервалами.

В настоящее время я делаю это следующим образом:

  1. взять оригинальные таймсерии.
  2. создавать новые таймсерии со значениями NaN через каждые 30 секунд (используя resample ('30S'). asfreq ())
  3. concat исходные таймсерии и новые таймсерии
  4. отсортируйте временные ряды, чтобы восстановить порядок времени (это мне не нравится - сортировка имеет сложность O = n log (n))
  5. интерполировать
  6. удалить исходные точки из таймсерий

есть способ попроще? как и в Matlab, у вас есть оригинальные временные ряды, и вы передаете новое время в качестве параметра функции interpolate () для получения значений в желаемое время. В идеале я бы хотел иметь такую ​​функцию, как

origTimeSeries.interpolate(newIndex=newTimeIndex, method='spline')

Замечу, что времена исходных таймсерий могут не быть подмножеством времен желаемых таймсерий.

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

values = [271238, 329285, 50, 260260, 263711]
timestamps = pd.to_datetime(['2015-01-04 08:29:4',
                             '2015-01-04 08:37:05',
                             '2015-01-04 08:41:07',
                             '2015-01-04 08:43:05',
                             '2015-01-04 08:49:05'])

ts = pd.Series(values, index=timestamps)
ts
ts[ts==-1] = np.nan
newFreq=ts.resample('60S').asfreq()

new=pd.concat([ts,newFreq]).sort_index()
new=new.interpolate(method='time')

ts.plot(marker='o')
new.plot(marker='+',markersize=15)

new[newFreq.index].plot(marker='.')

lines, labels = plt.gca().get_legend_handles_labels()
labels = ['original values (nonequispaced)', 'original + interpolated at new frequency (nonequispaced)', 'interpolated values without original values (equispaced!)']
plt.legend(lines, labels, loc='best')
plt.show()


image

Enhancement Resample Timeseries

Самый полезный комментарий

это вас довольно близко

In [42]: ts.reindex(ts.resample('60s').asfreq().index, method='nearest', tolerance=pd.Timedelta('60s')).interpolate('time')
Out[42]: 
2015-01-04 08:29:00    271238.000000
2015-01-04 08:30:00    271238.000000
2015-01-04 08:31:00    279530.428571
2015-01-04 08:32:00    287822.857143
2015-01-04 08:33:00    296115.285714
2015-01-04 08:34:00    304407.714286
2015-01-04 08:35:00    312700.142857
2015-01-04 08:36:00    320992.571429
2015-01-04 08:37:00    329285.000000
2015-01-04 08:38:00    329285.000000
2015-01-04 08:39:00    219540.000000
2015-01-04 08:40:00    109795.000000
2015-01-04 08:41:00        50.000000
2015-01-04 08:42:00        50.000000
2015-01-04 08:43:00    260260.000000
2015-01-04 08:44:00    260260.000000
2015-01-04 08:45:00    260950.200000
2015-01-04 08:46:00    261640.400000
2015-01-04 08:47:00    262330.600000
2015-01-04 08:48:00    263020.800000
2015-01-04 08:49:00    263711.000000
Freq: 60S, dtype: float64

Все 3 Комментарий

используйте order_merge, а не concat и sort
http://pandas.pydata.org/pandas-docs/stable/merging.html#merging -ordered-data

Было бы неплохо сделать это вообще без необходимости слияния, поскольку мне действительно не нужны объединенные временные ряды, мне нужен только результирующий равномерный временной ряд. Является ли описанный мной способ (улучшенный с помощью order_merge) наиболее эффективным способом сделать это? Может быть, тогда было бы лучше использовать пряный пряный

http://docs.scipy.org/doc/scipy-0.14.0/reference/tutorial/interpolate.html#d -interpolation-interp1d
scipy позволяет делать это в стиле Matlab, сохранять исходные таймсерии и передавать новый индекс для получения новых таймсерий.

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

это вас довольно близко

In [42]: ts.reindex(ts.resample('60s').asfreq().index, method='nearest', tolerance=pd.Timedelta('60s')).interpolate('time')
Out[42]: 
2015-01-04 08:29:00    271238.000000
2015-01-04 08:30:00    271238.000000
2015-01-04 08:31:00    279530.428571
2015-01-04 08:32:00    287822.857143
2015-01-04 08:33:00    296115.285714
2015-01-04 08:34:00    304407.714286
2015-01-04 08:35:00    312700.142857
2015-01-04 08:36:00    320992.571429
2015-01-04 08:37:00    329285.000000
2015-01-04 08:38:00    329285.000000
2015-01-04 08:39:00    219540.000000
2015-01-04 08:40:00    109795.000000
2015-01-04 08:41:00        50.000000
2015-01-04 08:42:00        50.000000
2015-01-04 08:43:00    260260.000000
2015-01-04 08:44:00    260260.000000
2015-01-04 08:45:00    260950.200000
2015-01-04 08:46:00    261640.400000
2015-01-04 08:47:00    262330.600000
2015-01-04 08:48:00    263020.800000
2015-01-04 08:49:00    263711.000000
Freq: 60S, dtype: float64
Была ли эта страница полезной?
0 / 5 - 0 рейтинги