Pandas: Interpolieren (Upsampling) von Zeitreihen ohne gleichen Abstand in 18.0rc1 . mit gleichem Abstand

Erstellt am 7. März 2016  ·  3Kommentare  ·  Quelle: pandas-dev/pandas

Ich möchte (hochskalierte) Zeitreihen ohne gleichen Abstand interpolieren, um Zeitreihen mit gleichem Abstand zu erhalten.

Zur Zeit mache ich es wie folgt:

  1. nimm originale Zeitreihen.
  2. neue Zeitreihen mit NaN-Werten alle 30 Sekunden erstellen (mit resample('30S').asfreq() )
  3. concat original timeseries und neue timeseries
  4. Sortieren Sie die Zeitreihen, um die Reihenfolge der Zeiten wiederherzustellen (Das gefällt mir nicht - das Sortieren hat eine Komplexität von O = n log(n) )
  5. interpolieren
  6. Originalpunkte aus der Zeitreihe entfernen

gibt es einen einfacheren weg? wie in Matlab haben Sie ursprüngliche Zeitreihen und Sie übergeben neue Zeiten als Parameter an die Funktion interpolate(), um Werte zu gewünschten Zeiten zu erhalten. Idealerweise hätte ich gerne eine Funktion wie

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

Ich bemerke, dass die Zeiten der ursprünglichen Zeitreihen möglicherweise keine Untermenge der Zeiten der gewünschten Zeitreihen sind.

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

Hilfreichster Kommentar

das kommt einem ziemlich nahe

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

Alle 3 Kommentare

benutze order_merge statt concat und sort
http://pandas.pydata.org/pandas-docs/stable/merging.html#merging -ordered-data

Es wäre schön, dies ganz ohne Zusammenführen zu tun, da ich die zusammengeführten Zeitreihen nicht wirklich benötige, sondern nur die resultierenden Zeitreihen mit gleichen Abständen. Ist der von mir beschriebene Weg (erweitert mit order_merge) der effizienteste Weg, dies zu tun? Vielleicht wäre es dann besser, scharf direkt zu verwenden

http://docs.scipy.org/doc/scipy-0.14.0/reference/tutorial/interpolate.html#d -interpolation-interp1d
scipy ermöglicht es, dies im Matlab-Stil zu tun, die ursprüngliche Zeitreihe beizubehalten und einen neuen Index zu übergeben, um neue Zeitreihen zu erhalten.

Außerdem werde ich mit Online-Daten arbeiten, damit die ursprüngliche Zeitreihe wächst und ich die neuen Daten interpolieren und der interpolierten (gleichbeabstandeten) Zeitreihe hinzufügen muss.

das kommt einem ziemlich nahe

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
War diese Seite hilfreich?
0 / 5 - 0 Bewertungen