Pandas: Interpoler (suréchantillonner) des séries temporelles non équidistantes en 18.0rc1 équidistantes

Créé le 7 mars 2016  ·  3Commentaires  ·  Source: pandas-dev/pandas

Je veux interpoler (upscale) des séries chronologiques non équidistantes pour obtenir des séries chronologiques équidistantes.

Actuellement, je le fais de la manière suivante :

  1. prendre des séries temporelles originales.
  2. créer de nouvelles séries temporelles avec des valeurs NaN toutes les 30 secondes ( en utilisant resample('30S').asfreq() )
  3. concaténer les séries temporelles originales et les nouvelles séries temporelles
  4. trier les séries temporelles pour restaurer l'ordre des temps (cela ne me plaît pas - le tri a une complexité de O = n log(n) )
  5. interpoler
  6. supprimer les points d'origine de la série temporelle

y a-t-il un moyen plus simple? comme dans matlab, vous avez des séries temporelles d'origine et vous passez de nouvelles heures en paramètre à la fonction interpolate() pour recevoir des valeurs aux heures souhaitées. Idéalement, j'aimerais avoir une fonction telle que

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

Je remarque que les heures des séries temporelles originales pourraient ne pas être un sous-ensemble des heures des séries temporelles souhaitées.

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

Commentaire le plus utile

cela vous rapproche assez

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

Tous les 3 commentaires

Ce serait bien de le faire sans avoir besoin de fusionner complètement puisque je n'ai pas vraiment besoin de la série chronologique fusionnée, j'ai seulement besoin de la série chronologique équidistante résultante. La manière que j'ai décrite (améliorée avec l'order_merge) est-elle la manière la plus efficace de le faire ? Peut-être qu'il serait préférable d'utiliser directement des épices

http://docs.scipy.org/doc/scipy-0.14.0/reference/tutorial/interpolate.html#d -interpolation-interp1d
scipy permet de le faire dans le style Matlab, de conserver la série temporelle d'origine et de passer un nouvel index pour obtenir de nouvelles séries temporelles.

Je travaillerai également sur des données en ligne afin que la série chronologique d'origine grandisse et je devrai interpoler les nouvelles données et les ajouter à la série chronologique interpolée (équidistante).

cela vous rapproche assez

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
Cette page vous a été utile?
0 / 5 - 0 notes