Update: Ich habe eine kurze Analyse der drei Antworten am Ende des Fragetextes bereitgestellt und meine Auswahlmöglichkeiten erläutert.Erstellen von festen Intervalldatensätzen aus zufälligen Intervalldatensätzen mit veralteten Daten
Meine Frage: Was ist die effizienteste Methode zum Erstellen eines festen Intervalldatensatzes aus einem Zufallsintervall-Dataset mit veralteten Daten?
Einige Hintergrund: Das oben genannte ist ein häufiges Problem in der Statistik. Häufig hat man eine Folge von Beobachtungen zu zufälligen Zeiten. Nennen Sie es Input
. Aber man möchte eine Folge von Beobachtungen, etwa alle 5 Minuten. Nennen Sie es Output
. Eine der gebräuchlichsten Methoden zum Erstellen dieses Datensatzes besteht darin, veraltete Daten zu verwenden, d. H. Jede Beobachtung in Output
gleich der zuletzt aufgetretenen Beobachtung in Input
einzustellen.
So, hier ist einige Code-Beispiel-Datensätze zu erstellen:
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)];
Beide Datensätze an der Jahrtausendwende in der Nähe von Mitternacht beginnen. Die Zeitstempel in Input
treten jedoch in zufälligen Intervallen auf, während die Zeitstempel in Output
in festen Intervallen auftreten. Der Einfachheit halber habe ich dafür gesorgt, dass die erste Beobachtung in Input
immer vor der ersten Beobachtung in Output
erfolgt. Fühlen Sie sich frei, diese Annahme in irgendwelchen Antworten zu machen.
Derzeit löse ich das Problem wie folgt aus:
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
Sicherlich gibt es eine effizientere, oder zumindest, eleganter Weg, um dieses Problem zu lösen? Wie ich bereits erwähnte, ist dies ein häufiges Problem in der Statistik. Vielleicht hat Matlab eine eingebaute Funktion, die mir nicht bekannt ist? Jede Hilfe würde sehr geschätzt werden, da ich diese Routine eine Menge für einige große Datensätze verwende.
DIE ANTWORTEN: Hallo zusammen, ich habe die drei Antworten analysiert, und wie sie sind, ist Angainor das Beste.
Die Antwort von ChthonicDaemon ist zwar am einfachsten zu implementieren, aber sehr langsam. Dies gilt auch dann, wenn die Konvertierung in ein Objekt timeseries
außerhalb des Geschwindigkeitstests erfolgt. Ich schätze, die resample
Funktion hat im Moment eine Menge Overhead. Ich laufe 2011b, also ist es möglich, dass Mathworks es in der Zwischenzeit verbessert hat. Außerdem benötigt diese Methode eine zusätzliche Zeile für den Fall, dass Output
mehr als eine Beobachtung nach Input
beendet.
Die Antwort von Rody läuft nur etwas langsamer als die von Angaindor (nicht überraschend, da beide den histc
Ansatz verwenden), scheint jedoch einige Probleme zu haben. Erstens ist das Verfahren zum Zuweisen der letzten Beobachtung in Output
nicht robust gegenüber der letzten Beobachtung in Input
, die nach der letzten Beobachtung in Output
auftritt. Dies ist eine einfache Lösung. Aber es gibt ein zweites Problem, von dem ich denke, dass es InputTimeStamp
als die erste Eingabe zu histc
statt der OutputTimeStamp
, die von Angainor angenommen wird, hat. Das Problem tritt auf, wenn Sie beim Einrichten der Beispieleingänge OutputTimeStamp = 730486.002 + (0:0.001:TOutput * 0.001 - 0.001)';
in OutputTimeStamp = 730486.002 + (0:0.0001:TOutput * 0.0001 - 0.0001)';
ändern.
Angainor scheint robust zu allem, was ich warf, und es war der schnellste.
ich viel Speed-Tests für verschiedene Eingangsspezifikationen haben - die folgenden Zahlen sind ziemlich repräsentativ:
Meine naive Schleife: Elapsed time is 8.579535 seconds.
Angainor: Elapsed time is 0.661756 seconds.
Rody: Elapsed time is 0.913304 seconds.
ChthonicDaemon: Elapsed time is 22.916844 seconds.
Ich bin + 1-Ing Angainor Lösung und markiert die Frage gelöst.
Nur klar zu sein: es ist wichtig, dass die Zeiten nicht in Ordnung sind? In den meisten Fällen werden Beobachtungen in streng aufsteigender Zeit gemacht. – chthonicdaemon
@chtonicdaemon Sie können davon ausgehen, dass die Zeiten in aufsteigender Reihenfolge sind. Ich habe anscheinend sowohl die "Zeitreihen" -Klasse als auch die "Resample" -Funktion in 2011b, daher sollte ich in der Lage sein, Ihre Antwort zu testen. Prost. –