2012-10-26 3 views
1

Это сообщение следует за предыдущий вопрос относительно реструктуризации матрицы:переформатирования матрицы в MATLAB с нан значения

re-formatting a matrix in matlab

Дополнительной проблемой сталкиваюсь демонстрируется на следующем примере:

depth = [0:1:20]'; 
data = rand(1,length(depth))'; 
d = [depth,data]; 
d = [d;d(1:20,:);d]; 

Здесь я хотел бы изменить эту матрицу так, чтобы каждый столбец представлял определенную глубину, и каждая строка представляет времени, поэтому в итоге у меня будет 3 строки (т. дней) и 21 столбец (т. е. измерение на каждой глубине). Однако мы не можем изменить это, потому что количество измерений за данный день не одинаково, то есть некоторые из них отсутствуют. Это известно:

dd = sortrows(d,1); 
for i = 1:length(depth); 
    e(i) = length(dd(dd(:,1)==depth(i),:)); 
end 

Из 'e' мы обнаруживаем, что количество глубин различно для разных дней. Как я мог вставить nan в матрицу, чтобы каждый день имел одинаковые значения глубины? Сначала я смог найти уникальные глубины:

уникальный (d (:, 1)) Из-за отсутствия глубины (от уникальной) в течение заданного дня я хотел бы вставить глубину в правильное положение и вставьте нан в соответствующее место в столбце данных. Как это можно достичь?

ответ

5

Вы правильно подумали, что unique может пригодиться здесь.Вам также нужен третий выходной аргумент, который отображает уникальные глубины на позиции в исходном векторе d. взгляните на этот код - комментарии объясняют, что я делаю

% find unique depths and their mapping onto the d array 
[depths, ~, j] = unique(d(:,1)); 

% find the start of every day of measurements 
% the assumption here is that the depths for each day are in increasing order 
days_data = [1; diff(d(:,1))<0]; 

% count the number of days 
ndays = sum(days_data); 

% map every entry in d to the correct day 
days_data = cumsum(days_data); 

% construct the output array full of nans 
dd = nan(numel(depths), ndays); 

% assing the existing measurements using linear indices 
% Where data does not exist, NaN will remain 
dd(sub2ind(size(dd), j, days_data)) = d(:,2) 

dd = 

0.5115 0.5115 0.5115 
0.8194 0.8194 0.8194 
0.5803 0.5803 0.5803 
0.9404 0.9404 0.9404 
0.3269 0.3269 0.3269 
0.8546 0.8546 0.8546 
0.7854 0.7854 0.7854 
0.8086 0.8086 0.8086 
0.5485 0.5485 0.5485 
0.0663 0.0663 0.0663 
0.8422 0.8422 0.8422 
0.7958 0.7958 0.7958 
0.1347 0.1347 0.1347 
0.8326 0.8326 0.8326 
0.3549 0.3549 0.3549 
0.9585 0.9585 0.9585 
0.1125 0.1125 0.1125 
0.8541 0.8541 0.8541 
0.9872 0.9872 0.9872 
0.2892 0.2892 0.2892 
0.4692  NaN 0.4692 

Возможно, вы захотите перенести матрицу.

1

Непонятно, что ваши данные выглядят точно, но следующее может помочь вам в ответе.

Предположим, у вас есть вектор-столбец

day1 = 1:21';

и, первоначально, все значения NaN

day1(:) = NaN

Предположим далее, что у вас есть 2d массив измерений, в которых первая колонка представляет глубины, а вторая - измерения на этих глубинах. Например

msrmnts = [1,2;2,3;4,5;6,7] % etc

тогда присваивания

day1(msrmnts(:,1)) = msrmnts(:,2)

будет установить значения только в тех строках day1, индексы которых находятся в первом столбце msrmnts. Этот второй оператор использует возможность Matlab для используя один массив в качестве набора индексов в другой массив, например

д ([9 7-12 4]) = 1: 5

бы установить элементы [9 7 8 12 4] из d к значения 1:5. Обратите внимание, что индексы элементов не обязательно должны быть в порядке. Вы даже можете вставить одно и то же значение несколько раз в массив индексов, например [4 4 5 6 3 4], хотя это не очень полезно.

Смежные вопросы