更新:質問テキストの下部にある 3 つの回答の簡単な分析を提供し、私の選択を説明しました。
私の質問:古いデータを使用してランダムな間隔のデータセットから固定間隔のデータセットを構築する最も効率的な方法は何ですか?
いくつかの背景:上記は、統計における一般的な問題です。多くの場合、一連の観測がランダムな時間に発生します。それを呼び出しますInput
。しかし、たとえば 5 分ごとに発生する一連の観測が必要です。それを呼び出しますOutput
。このデータセットを構築する最も一般的な方法の 1 つは、古いデータを使用することです。つまり、各観測Output
値を で最も最近発生した観測値と同じに設定しInput
ます。
そのため、サンプル データセットを構築するためのコードを次に示します。
TInput = 100;
TOutput = 50;
InputTimeStamp = 730486 + cumsum(0.001 * rand(TInput, 1));
Input = [InputTimeStamp, randn(TInput, 1)];
OutputTimeStamp = 730486.002 + (0:0.001:TOutput * 0.001 - 0.001)';
Output = [OutputTimeStamp, NaN(TOutput, 1)];
どちらのデータセットも、千年紀の変わり目の真夜中近くに始まります。ただし、 のタイムスタンプはInput
ランダムな間隔で発生しますが、 のタイムスタンプはOutput
一定の間隔で発生します。簡単にするために、 の最初の観測がInput
常に の最初の観測の前に発生するようにしましたOutput
。どの回答でも、この仮定を自由に行ってください。
現在、次のように問題を解決しています。
sMax = size(Output, 1);
tMax = size(Input, 1);
s = 1;
t = 2;
%#Loop over input data
while t <= tMax
if Input(t, 1) > Output(s, 1)
%#If current obs in Input occurs after current obs in output then set current obs in output equal to previous obs in input
Output(s, 2:end) = Input(t-1, 2:end);
s = s + 1;
%#Check if we've filled out all observations in output
if s > sMax
break
end
%#This step is necessary in case we need to use the same input observation twice in a row
t = t - 1;
end
t = t + 1;
if t > tMax
%#If all remaining observations in output occur after last observation in input, then use last obs in input for all remaining obs in output
Output(s:end, 2:end) = Input(end, 2:end);
break
end
end
確かに、この問題を解決するためのより効率的な、または少なくともよりエレガントな方法はありますか? 前述したように、これは統計の一般的な問題です。おそらくMatlabには、私が気付いていない組み込み関数がありますか? いくつかの大規模なデータセットに対してこのルーチンをたくさん使用しているので、どんな助けでも大歓迎です。
答え:こんにちは、私は 3 つの答えを分析しました。
ChthonicDaemon の答えは、実装が明らかに最も簡単ですが、非常に遅いです。これは、オブジェクトへの変換がtimeseries
速度テストの外で行われる場合でも当てはまります。現時点では、このresample
関数には多くのオーバーヘッドがあると思います。私は 2011b を実行しているので、その間に Mathworks によって改善された可能性があります。また、このメソッドは、 のOutput
後に複数の観測が終了する場合に備えて、追加の行が必要Input
です。
Rody の回答は、Angainor の回答よりもわずかに遅いだけですが (どちらもこのhistc
アプローチを採用していることを考えると驚くことではありません)、いくつかの問題があるようです。まず、 の最後の観測を割り当てる方法は、 の最後の観測の後に発生するOutput
の最後の観測に対してロバストではありません。これは簡単な修正です。しかし、Angainor によって採用されたのではなく、最初の入力として持っていることに起因すると思われる 2 番目の問題があります。サンプル入力を設定するときに に変更すると、問題が発生します。Input
Output
InputTimeStamp
histc
OutputTimeStamp
OutputTimeStamp = 730486.002 + (0:0.001:TOutput * 0.001 - 0.001)';
OutputTimeStamp = 730486.002 + (0:0.0001:TOutput * 0.0001 - 0.0001)';
Angainor は、私が投げたすべてのものに対して堅牢であるように見え、さらに最速でした。
さまざまな入力仕様に対して多くの速度テストを行いました。次の数値はかなり代表的なものです。
私の素朴なループ:Elapsed time is 8.579535 seconds.
アンガノール:Elapsed time is 0.661756 seconds.
ロディ:Elapsed time is 0.913304 seconds.
ChthonicDaemon:Elapsed time is 22.916844 seconds.
Angainor のソリューションに +1 を付けて、質問に解決済みのマークを付けます。