Pandas: 等間隔でない時系列を等間隔の18.0rc1に内挿(アップサンプル)します

作成日 2016年03月07日  ·  3コメント  ·  ソース: pandas-dev/pandas

等間隔の時系列を取得するために、等間隔でない時系列を補間(アップスケール)したいと思います。

現在、私は次の方法でそれを行っています:

  1. オリジナルの時系列を取ります。
  2. 30秒間隔ごとにNaN値を使用して新しい時系列を作成します(resample( '30S')。asfreq()を使用)
  3. 元の時系列と新しい時系列を連結します
  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件

連結してソートするのではなく、ordered_mergeを使用する
http://pandas.pydata.org/pandas-docs/stable/merging.html#merging -ordered-data

マージされた時系列は実際には必要なく、結果として得られる等間隔の時系列のみが必要なので、マージをまったく必要とせずに実行すると便利です。 私が説明した方法(ordered_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 評価