2012-10-03 58 views
6

Cập nhật: Tôi đã cung cấp phân tích ngắn gọn ba câu trả lời ở cuối câu hỏi và giải thích các lựa chọn của tôi.Xây dựng tập dữ liệu khoảng thời gian cố định từ tập dữ liệu khoảng thời gian ngẫu nhiên sử dụng dữ liệu cũ

Câu hỏi của tôi: Phương pháp hiệu quả nhất để xây dựng tập dữ liệu khoảng cố định từ tập dữ liệu khoảng cách ngẫu nhiên bằng dữ liệu cũ là gì?

Một số nền: Ở trên là một vấn đề phổ biến trong thống kê. Thông thường, người ta có một chuỗi các quan sát xảy ra vào những thời điểm ngẫu nhiên. Gọi nó là Input. Nhưng người ta muốn một chuỗi các quan sát xảy ra, cứ 5 phút một lần. Gọi nó là Output. Một trong những phương pháp phổ biến nhất để tạo tập dữ liệu này là sử dụng dữ liệu cũ, tức là đặt từng quan sát trong Output bằng quan sát gần đây nhất xảy ra trong Input.

Vì vậy, đây là một số mã để xây dựng bộ dữ liệu Ví dụ:

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)]; 

Cả hai bộ dữ liệu bắt đầu từ gần nửa đêm tại thời điểm chuyển giao thiên niên kỷ. Tuy nhiên, dấu thời gian trong Input xảy ra vào khoảng thời gian ngẫu nhiên trong khi dấu thời gian trong Output xảy ra theo khoảng thời gian cố định. Để đơn giản, tôi đã đảm bảo rằng quan sát đầu tiên trong Input luôn xảy ra trước khi quan sát đầu tiên trong Output. Cảm thấy tự do để đưa ra giả định này trong bất kỳ câu trả lời nào.

Hiện nay, tôi giải quyết vấn đề như thế này:

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 

Chắc chắn có một hiệu quả hơn, hoặc ít nhất, cách thanh lịch hơn để giải quyết vấn đề này? Như tôi đã đề cập, đây là một vấn đề phổ biến trong thống kê. Có lẽ Matlab có một số chức năng trong xây dựng mà tôi không biết? Bất kỳ trợ giúp sẽ được nhiều đánh giá cao như tôi sử dụng thường xuyên này một LOT cho một số bộ dữ liệu lớn.

câu trả lời: Hi all, Tôi đã phân tích ba câu trả lời, và khi họ đứng, Angainor là tốt nhất.

Câu trả lời của ChthonicDaemon, trong khi rõ ràng là dễ thực hiện nhất, rất chậm. Điều này đúng ngay cả khi việc chuyển đổi sang đối tượng timeseries được thực hiện ngoài kiểm tra tốc độ. Tôi đoán các chức năng resample có rất nhiều chi phí tại thời điểm này. Tôi đang chạy 2011b, vì vậy có thể Mathworks đã cải thiện nó trong thời gian can thiệp. Ngoài ra, phương pháp này cần thêm dòng cho trường hợp số Output kết thúc nhiều lần quan sát sau Input.

Câu trả lời của Rody chỉ chạy chậm hơn một chút so với Angainor (không ngạc nhiên khi cả hai đều sử dụng cách tiếp cận histc), tuy nhiên, dường như có một số vấn đề. Đầu tiên, phương pháp chỉ định quan sát cuối cùng trong Output không mạnh mẽ đối với quan sát cuối cùng trong Input xảy ra sau lần quan sát cuối cùng trong Output. Đây là một cách sửa chữa dễ dàng. Nhưng có một vấn đề thứ hai mà tôi nghĩ bắt nguồn từ việc có InputTimeStamp làm đầu vào đầu tiên cho histc thay vì số OutputTimeStamp được Angainor chấp nhận. Sự cố sẽ xuất hiện nếu bạn thay đổi OutputTimeStamp = 730486.002 + (0:0.001:TOutput * 0.001 - 0.001)'; thành OutputTimeStamp = 730486.002 + (0:0.0001:TOutput * 0.0001 - 0.0001)'; khi thiết lập đầu vào mẫu.

Angainor xuất hiện mạnh mẽ với mọi thứ tôi đã ném vào nó, cộng với đó là nhanh nhất.

tôi đã có rất nhiều bài kiểm tra tốc độ cho thông số kỹ thuật đầu vào khác nhau - những con số sau đây là khá tiêu biểu:

loop ngây thơ của tôi: 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.

Tôi là giải pháp Angainor + 1-ing và đánh dấu câu hỏi được giải quyết.

+0

Chỉ cần được rõ ràng: là điều quan trọng là thời gian được tính không theo thứ tự? Trong hầu hết các trường hợp, các quan sát được thực hiện trong thời gian tăng dần nghiêm ngặt. – chthonicdaemon

+0

@chthonicdaemon Bạn có thể giả định thời gian theo thứ tự tăng dần. Tôi dường như có cả lớp 'timeseries' và' resample' trong năm 2011b, vì vậy tôi có thể kiểm tra câu trả lời của bạn. Chúc mừng. –

Trả lời

1

Đây là vấn đề của tôi về vấn đề này. histc là con đường để đi:

% find Output timestamps in Input bins 
N = histc(Output(:,1), Input(:,1)); 

% find counts in the non-empty bins 
counts = N(find(N)); 

% find Input signal value associated with every bin 
val = Input(find(N),2); 

% now, replicate every entry entry in val 
% as many times as specified in counts 
index = zeros(1,sum(counts)); 
index(cumsum([1 counts(1:end-1)'])) = 1; 
index = cumsum(index); 
val_rep = val(index) 

% finish the signal with last entry from Input, as needed 
val_rep(end+1:size(Output,1)) = Input(end,2); 

% done 
Output(:,2) = val_rep; 

Tôi đã kiểm tra lại quy trình của bạn cho một vài mô hình đầu vào khác nhau (Tôi đã thay đổi số timestamps Output) và kết quả đều giống nhau. Tuy nhiên, tôi vẫn không chắc chắn tôi đã hiểu vấn đề của bạn, vì vậy nếu có điều gì sai ở đây, hãy cho tôi biết.

+0

Tôi đã giải thích các lựa chọn của mình và thêm một phân tích ngắn gọn tất cả 3 câu trả lời vào cuối câu hỏi. Cảm ơn một lần nữa cho câu trả lời của bạn. –

2

Phương pháp "dữ liệu cũ" này được gọi là zero order hold trong trường tín hiệu và khoảng thời gian. Tìm kiếm điều này nhanh chóng mang đến nhiều giải pháp. Nếu bạn có Matlab 2012b, đây là tất cả được xây dựng vào lớp timeseries bằng resample chức năng, vì vậy bạn chỉ đơn giản là sẽ làm

TInput = 100; 
TOutput = 50; 

InputTimeStamp = 730486 + cumsum(0.001 * rand(TInput, 1)); 
InputData = randn(TInput, 1); 
InputTimeSeries = timeseries(InputData, InputTimeStamp); 

OutputTimeStamp = 730486.002 + (0:0.001:TOutput * 0.001 - 0.001); 
OutputTimeSeries = resample(InputTimeSeries, OutputTimeStamp, 'zoh'); % zoh stands for zero order hold 
+0

Cảm ơn câu trả lời. Tôi không nghĩ rằng 'loại' là cần thiết vì đầu ra của' rand' là hoàn toàn tích cực, do đó, một tổng tích lũy trên nó nên tăng đơn điệu có? –

+0

Tôi đã giải thích các lựa chọn của mình và thêm một phân tích ngắn gọn gồm cả 3 câu trả lời vào cuối câu hỏi. Cảm ơn một lần nữa cho câu trả lời của bạn. –

+0

Tôi đã bỏ lỡ phần cumsum, cảm ơn. Tôi hơi ngạc nhiên khi mẫu được dựng sẵn quá chậm, nhưng tôi cho rằng nó giống như rất nhiều thứ trong Matlab, cách tiếp cận chung thực hiện rất nhiều kiểm tra để đảm bảo sự vững chắc, v.v. – chthonicdaemon

Các vấn đề liên quan