2013-09-02 3 views
1

У меня есть матрица с одним столбцом, содержащим данные (один образец в секунду) и другой столбец с меткой времени в секундах. Есть несколько секунд, когда данные не меняются от последнего, и из-за этого не отображается на векторе. Я хотел применить функцию, такую ​​как простое среднее, к временным интервалам (например, 30 секунд). Но для этого Я должен посчитать с отсутствующими секундами. Каков наилучший способ сделать это?MATLAB: повторяющиеся элементы в векторе с возрастающей меткой времени

  1. Создайте первую матрицу с повторяющимися элементами (я также хотел бы иметь правильные временные метки для отсутствующих секунд включенных - самая сложная часть) и только затем вычислять средства;

или

  1. Используйте цикл (худший путь, я полагаю), чтобы вычислить среднее время вставки недостающих образцов;

Заранее благодарен!

ps .: ИЛИ Можно ли применять функции к идентификации данных и автоматически вводить (путем повторения) недостающие данные?

+0

Позвольте мне получить это право: когда вы участка точек с теми же данными и значениями временных меток, они перекрывают друг друга. Как же тогда получить средние значения? –

ответ

2

Вы можете использовать комбинацию diff и sum включить «недостающие» записи через взвешенного усреднения:

% time step 
step = 1; 

% Example data (with repeated elements) 
A = [... 
    1 80.6 
    2 79.8 
    3 40.3 
    4 40.3 
    5 81.9 
    6 83.6 
    7 83.7 
    8 95.4 
    9 14.8 
    10 14.8 
    11 14.8 
    12 14.8 
    13 14.8 
    14 44.3]; 

% Example data, with the repeated elements removed 
B = [... 
    1 80.6 
    2 79.8 
    3 40.3  
    5 81.9 
    6 83.6 
    7 83.7 
    8 95.4 
    9 14.8  
    14 44.3]; 

% The correct value 
M = mean(A(:,2)) 

% The correct value for the pruned data 
D = diff(B(:,1)); 
W = [D/step; 1]; 
M = sum(W .* B(:,2))/sum(W) 

Результаты:

M1 = 
    5.027857142857141e+001 
M2 = 
    5.027857142857143e+001 

В качестве альтернативы, вы можете воссоздать полный вектор A от сокращенного B через кодирование длины пробега. Вы можете сделать это эффективно так:

W = [diff(B(:,1))/step; 1]; 
idx([cumsum([true; W(W>0)])]) = true; 

A_new = [ (B(1,1):step:B(end,1)).' B(cumsum(idx(1:find(idx,1,'last')-1)),2) ]; 
+1

Приятный трюк для вычисления средневзвешенного значения. Единственная небольшая ошибка, которую я вижу, заключается в том, что вы взвешиваете последний элемент со значением 1, который работает в вашем примере, но не в общем случае. Вероятно, вы должны заменить его минимальным шагом времени. –

+0

@BasSwinckels: Это, конечно, верно. Я отредактирую его, спасибо! –

+0

Это работает, предположим, что у нас будет минимальная временная метка в данных, верно? если нет, объявление переменной с интервалом выборки должно работать, правильно? – XanderW

1

Вы можете дать каждому образцу вес, который отражает количество образцов, которые он фактически представляет. Такой вес может быть вычислен с diff:

data = [1 1; 0 2; 3 5; 4 7]; % Example data. Second column is timestamp 

weights = diff([data(:,2); data(end,2)+1]); % We assume the last sample 
% only represents itself 
result = sum(data(:,1).*weights)/sum(weights); 
Смежные вопросы