25

次のようなパンダの時系列があります。

                     Values
1992-08-27 07:46:48    28.0  
1992-08-27 08:00:48    28.2  
1992-08-27 08:33:48    28.4  
1992-08-27 08:43:48    28.8  
1992-08-27 08:48:48    29.0  
1992-08-27 08:51:48    29.2  
1992-08-27 08:53:48    29.6  
1992-08-27 08:56:48    29.8  
1992-08-27 09:03:48    30.0

値が線形補間される 15 分の時間ステップで定期的な時系列にリサンプリングしたいと思います。基本的に私は取得したい:

                     Values
1992-08-27 08:00:00    28.2  
1992-08-27 08:15:00    28.3  
1992-08-27 08:30:00    28.4  
1992-08-27 08:45:00    28.8  
1992-08-27 09:00:00    29.9

ただし、Pandas の resample メソッド (df.resample('15Min')) を使用すると、次のようになります。

                     Values
1992-08-27 08:00:00   28.20  
1992-08-27 08:15:00     NaN  
1992-08-27 08:30:00   28.60  
1992-08-27 08:45:00   29.40  
1992-08-27 09:00:00   30.00  

'how' および 'fill_method' パラメータを変えて resample メソッドを試してみましたが、思い通りの結果が得られませんでした。間違った方法を使用していますか?

これはかなり単純なクエリだと思いますが、しばらくの間 Web を検索しましたが、答えが見つかりませんでした。

私が得ることができる助けを前もって感謝します。

4

4 に答える 4

19

tracesでこれを行うことができます。まず、TimeSeries辞書のように不規則な測定値で を作成します。

ts = traces.TimeSeries([
    (datetime(1992, 8, 27, 7, 46, 48), 28.0),
    (datetime(1992, 8, 27, 8, 0, 48), 28.2),
    ...
    (datetime(1992, 8, 27, 9, 3, 48), 30.0),
])

次に、sampleメソッドを使用して正則化します。

ts.sample(
    sampling_period=timedelta(minutes=15),
    start=datetime(1992, 8, 27, 8),
    end=datetime(1992, 8, 27, 9),
    interpolate='linear',
)

これにより、次の正則化バージョンが生成されます。灰色の点は元のデータで、オレンジ色は線形補間による正則化バージョンです。

線形補間による時系列

補間値は次のとおりです。

1992-08-27 08:00:00    28.189 
1992-08-27 08:15:00    28.286  
1992-08-27 08:30:00    28.377
1992-08-27 08:45:00    28.848
1992-08-27 09:00:00    29.891
于 2016-09-27T16:57:14.913 に答える
14

@mstringer が取得するのと同じ結果は、純粋に pandas で実現できます。秘訣は、最初に秒単位でリサンプリングし、補間を使用して中間値を埋め ( .resample('s').interpolate())、次に 15 分間でアップサンプリングする ( .resample('15T').asfreq()) ことです。

import io
import pandas as pd

data = io.StringIO('''\
Values
1992-08-27 07:46:48,28.0  
1992-08-27 08:00:48,28.2  
1992-08-27 08:33:48,28.4  
1992-08-27 08:43:48,28.8  
1992-08-27 08:48:48,29.0  
1992-08-27 08:51:48,29.2  
1992-08-27 08:53:48,29.6  
1992-08-27 08:56:48,29.8  
1992-08-27 09:03:48,30.0
''')
s = pd.read_csv(data, squeeze=True)
s.index = pd.to_datetime(s.index)

res = s.resample('s').interpolate().resample('15T').asfreq().dropna()
print(res)

出力:

1992-08-27 08:00:00    28.188571
1992-08-27 08:15:00    28.286061
1992-08-27 08:30:00    28.376970
1992-08-27 08:45:00    28.848000
1992-08-27 09:00:00    29.891429
Freq: 15T, Name: Values, dtype: float64
于 2016-09-27T17:18:23.793 に答える
9

少し手間がかかりますが、これを試してみてください。基本的な考え方は、各リサンプル ポイントに最も近い 2 つのタイムスタンプを見つけて補間することです。 np.searchsortedリサンプル ポイントに最も近い日付を見つけるために使用されます。

# empty frame with desired index
rs = pd.DataFrame(index=df.resample('15min').iloc[1:].index)

# array of indexes corresponding with closest timestamp after resample
idx_after = np.searchsorted(df.index.values, rs.index.values)

# values and timestamp before/after resample
rs['after'] = df.loc[df.index[idx_after], 'Values'].values
rs['before'] = df.loc[df.index[idx_after - 1], 'Values'].values
rs['after_time'] = df.index[idx_after]
rs['before_time'] = df.index[idx_after - 1]

#calculate new weighted value
rs['span'] = (rs['after_time'] - rs['before_time'])
rs['after_weight'] = (rs['after_time'] - rs.index) / rs['span']
# I got errors here unless I turn the index to a series
rs['before_weight'] = (pd.Series(data=rs.index, index=rs.index) - rs['before_time']) / rs['span']

rs['Values'] = rs.eval('before * before_weight + after * after_weight')

結局のところ、うまくいけば正しい答え:

In [161]: rs['Values']
Out[161]: 
1992-08-27 08:00:00    28.011429
1992-08-27 08:15:00    28.313939
1992-08-27 08:30:00    28.223030
1992-08-27 08:45:00    28.952000
1992-08-27 09:00:00    29.908571
Freq: 15T, Name: Values, dtype: float64
于 2014-08-11T23:03:31.547 に答える