extract user defined data from matrix in GUI

2 Ansichten (letzte 30 Tage)
JB
JB am 5 Okt. 2017
Kommentiert: Jan am 9 Okt. 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 Kommentare
Jan
Jan am 5 Okt. 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 am 5 Okt. 2017
Hi Jan Simon. You are absolutely right. I have corrected in the question above. Thanks a lot.

Melden Sie sich an, um zu kommentieren.

Antworten (1)

Jan
Jan am 5 Okt. 2017
Bearbeitet: Jan am 5 Okt. 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 Kommentare
Jan
Jan am 9 Okt. 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 am 9 Okt. 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);

Melden Sie sich an, um zu kommentieren.

Kategorien

Mehr zu Programming finden Sie in Help Center und File Exchange

Tags

Produkte

Community Treasure Hunt

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

Start Hunting!

Translated by