MATLAB Answers

extract user defined data from matrix in GUI

조회 수: 2(최근 30일)
JB
JB 5 Oct 2017
Commented: Jan 9 Oct 2017
This might be a simple question but I still need some help to sort this out. I have Dataset and from this the user defines which columns to extract from a uitable. I can get the uitable data which will look like the "sample" below:
Dataset =
1 2 3 4 5 6
5 6 7 8 9 10
10 20 30 40 50 60
100 200 300 400 500 600
sample =
1 3 0
2 4 6
Now I want to extract the columns specified in each "sample" row of the Dataset and calculate the mean and finally create a new matrix with then calculated means in each column. The result would be:
new =
2 4
6 8
20 40
200 400
Sorry for the clumsy description, but I hope I makes sense. But any help is very appreciated. The above example is a simplified example. The Dataset I ahve is very large andso is the "sample" set (many rows x 3 columns),so I believe a loop will solve the issue but please let me know if you have other ideas. Thanks

  댓글 수: 2

Jan
Jan 5 Oct 2017
I read the question 5 times now, without understanding it. You want to extract columns from matrix DataSet. These columns are "specified in each row of sample". The first row is [1,3,0]. Perhaps this means the 1st and 3rd column of DataSet. But then the mean would be [2, 6, 20, 200]. Is the leading 1 a typo?
Now the 2nd row: [2,4,6]. The corresponding columns are:
2 4 6
6 8 10
20 40 60
200 400 600
And again the mean is not [4, 12, 40, 400], but the 2nd element would be 8.
Please clarify this.
JB
JB 5 Oct 2017
Hi Jan Simon. You are absolutely right. I have corrected in the question above. Thanks a lot.

로그인 to comment.

답변 수 (1)

Jan
Jan 5 Oct 2017
Jan 님이 편집함. 5 Oct 2017
DataSet = [ ...
1 2 3 4 5 6; ...
5 6 7 8 9 10; ...
10 20 30 40 50 60; ...
100 200 300 400 500 600];
sample = [1 3 0; ...
2 4 6];
nSample = size(sample, 1);
Avg = zeros(size(DataSet, 1), nSample);
for k = 1:nSample
index = sample(k, :);
index = index(index ~= 0);
Avg(:, k) = sum(DataSet(:, index), 2) / numel(index); % Faster than mean()
end
Does this produce the wanted output? If so, let's think of vectorizing this:
wData = size(DataSet, 1);
[nSample, wSample] = size(sample);
nValidSample = sum(sample ~= 0, 2).';
% Insert a column of zeros to handle the 0 in sample:
DataPad = cat(2, zeros(wData, 1), DataSet);
% Shift the indices in sample and use them as column index:
Sampled = DataPad(:, sample.' + 1);
% Create blocks to sum over:
Sampled = reshape(Sampled, wData, wSample, nSample);
% Average over blocks: (! Auto-Expand, >= R2016b !)
Avg = reshape(sum(Sampled, 2), wData, nSample) ./ nValidSample;
For older Matlab versions the last line is slightly slower:
Summed = reshape(sum(Sampled, 2), wData, nSample);
Avg = bsxfun(@rdivide, Summed, nValidSample);
A speed comparison (R2016b/64):
DataSet = rand(4, 1e3);
sample = randi([0, 1e3], 1e6, 3);
Loop: 6.46 sec
Vectorized: 0.36 sec

  댓글 수: 3

JB
JB 5 Oct 2017
BRILLIANT. It does exactly what I want. Thanks a million.
Jan
Jan 9 Oct 2017
Copied from the section for answers: [JB wrote:]
@Jan Simon. Once again thanks a lot for your great help. I am working with MATLAB R2015b/32 and get an error in the last code line:
Error using ./ Matrix dimensions must agree.
Am i making a mistake or???
Jan
Jan 9 Oct 2017
Please read my answer carefully. I repeat:
% Average over blocks: (! Auto-Expand, *** >= R2016b *** !)
Avg = reshape(sum(Sampled, 2), wData, nSample) ./ nValidSample;
For older Matlab versions the last line is slightly slower:
Summed = reshape(sum(Sampled, 2), wData, nSample);
Avg = bsxfun(@rdivide, Summed, nValidSample);

로그인 to comment.

이 질문에 답변하려면 로그인을(를) 수행하십시오.

태그

제품


Translated by