Pandas: Interpolar (upsample) séries temporais não equidistantes em 18.0rc1 equidistantes

Criado em 7 mar. 2016  ·  3Comentários  ·  Fonte: pandas-dev/pandas

Eu quero interpolar (upscale) séries temporais não espaçadas para obter séries temporais equidistantes.

Atualmente estou fazendo isso da seguinte maneira:

  1. pegue séries temporais originais.
  2. crie novas séries temporais com valores NaN a cada intervalo de 30 segundos (usando resample ('30S'). asfreq ())
  3. concat séries do tempo originais e novas séries do tempo
  4. classificar a série do tempo para restaurar a ordem dos tempos (isso eu não gosto - a classificação tem complexidade de O = n log (n))
  5. interpolar
  6. remover pontos originais da série do tempo

existe uma maneira mais simples? como no matlab, você tem séries de tempo originais e passa novos tempos como um parâmetro para a função interpolate () para receber valores nos tempos desejados. Idealmente, gostaria de ter uma função como

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

Observo que os tempos das séries do tempo originais podem não ser um subconjunto dos tempos das séries do tempo desejadas.

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

Comentários muito úteis

isso te deixa bem perto

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

Todos 3 comentários

use Order_merge em vez de concat e classificar
http://pandas.pydata.org/pandas-docs/stable/merging.html#merging -ordered-data

Seria bom fazer isso sem a necessidade de mesclar completamente, já que não preciso realmente da série temporal mesclada, preciso apenas da série temporal equidistante resultante. A maneira que descrevi (aprimorada com o order_merge) é a maneira mais eficiente de fazer isso? Talvez usar picante diretamente seja melhor então

http://docs.scipy.org/doc/scipy-0.14.0/reference/tutorial/interpolate.html#d -interpolation-interp1d
scipy permite fazer isso no estilo Matlab, manter a série do tempo original e passar um novo índice para obter novas séries do tempo.

Além disso, estarei trabalhando com dados online para que a série temporal original cresça e precisarei interpolar os novos dados e adicioná-los à série temporal interpolada (equidistante).

isso te deixa bem perto

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
Esta página foi útil?
0 / 5 - 0 avaliações