extract user defined data from matrix in GUI

조회 수: 2 (최근 30일)
JB
JB 2017년 10월 5일
댓글: Jan 2017년 10월 9일
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 2017년 10월 5일
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 2017년 10월 5일
Hi Jan Simon. You are absolutely right. I have corrected in the question above. Thanks a lot.

댓글을 달려면 로그인하십시오.

답변 (1개)

Jan
Jan 2017년 10월 5일
편집: Jan 2017년 10월 5일
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
Jan
Jan 2017년 10월 9일
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 2017년 10월 9일
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);

댓글을 달려면 로그인하십시오.

카테고리

Help CenterFile Exchange에서 Programming에 대해 자세히 알아보기

태그

제품

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by