MATLAB Answers

Use arrayfun and cellfun to avoid for-loops

27 ビュー (過去 30 日間)
Jannis Korn
Jannis Korn 2021 年 1 月 16 日
コメント済み: Walter Roberson 2021 年 1 月 16 日
Hey there,
I am currently getting used to all the functions provided by MATLAB, so I am unfortunately not entirely sure how to fully utilize cellfun and arrayfun.
I was wondering, whether there are faster workarounds for for-loops, e.g.
for i= 1:length(Categories)-1
for j= i+1:length(Categories)
% separated_data is a 3D array of data, I want to get the p-Values for the data matching
% several numerated categories here
p=vertcat(p,[i,j,ranksum(separated_data(:,1,i),separated_data(:,1,j)),...
ranksum(separated_data(:,2,i),separated_data(:,2,j)),ranksum(separated_data(:,3,i),separated_data(:,3,j))]);
end
end
Another one would be a routine I am trying to write to more conveniently import my data (I know there are a lot of workarounds, but I am writing my own for practice and to meet the special formatting of my data). Here's my plan:
  • Get the file name (done)
  • Obtaining the header titles and enumerating them, then ask the user to give a vector with the columns they want to import (done)
  • Create a cell array by repmat({'%*f'},1,max(input_vector)) (done)
  • Now I want to remove the asterisks for all the elements given in the input_vector
I have tried using cellfun and arrayfun, but once again I am not familiar enough with them to get it to work without a for-loop. Therefore, here is my current code for that issue:
columns = input('Enter which columns you''d like to import as a vector:\n');
format = horzcat(repmat({'%*f'},1,max(columns)),{'%*[^\n]'});
for i = 1:length(columns)
format{i} = erase(format{i},'*');
end
I'd be grateful for any advice related to the given problems, but also if you know a more detailed description of cellfun, arrayfun and these things (helping to optimize resources, runtime, etc.) than provided by
doc cellfun
doc arrayfun
Thanks in advance!

  0 件のコメント

サインインしてコメントする。

採用された回答

Walter Roberson
Walter Roberson 2021 年 1 月 16 日
for i= 1:length(Categories)-1
for j= i+1:length(Categories)
% separated_data is a 3D array of data, I want to get the p-Values for the data matching
% several numerated categories here
p=vertcat(p,[i,j,ranksum(separated_data(:,1,i),separated_data(:,1,j)),...
ranksum(separated_data(:,2,i),separated_data(:,2,j)),ranksum(separated_data(:,3,i),separated_data(:,3,j))]);
end
end
That code has to expand p every time through the loop, which is inefficient.
nC = length(Categories);
pto = cell(nC-1,1);
for i= 1:nC-1
nleft = nC - i;
pt = cell(nleft, 1);
for j= i+1:length(Categories)
% separated_data is a 3D array of data, I want to get the p-Values for the data matching
% several numerated categories here
pt{j-i} = [i,j,ranksum(separated_data(:,1,i),separated_data(:,1,j)),...
ranksum(separated_data(:,2,i),separated_data(:,2,j)),ranksum(separated_data(:,3,i),separated_data(:,3,j))];
end
pto{i} = vertcat(pt{:});
end
p = vertcat(pto{:});
The above does not need to expand any arrays.

  1 件のコメント

Walter Roberson
Walter Roberson 2021 年 1 月 16 日
columns = input('Enter which columns you''d like to import as a vector:\n');
clear fmt
fmt(1:max(columns)) = {'%*f'};
fmt(columns) = {'%f'};
fmt{end+1} = '%*[^\n]';
fmt = horzcat(fmt{:});
I changed variable names to avoid conflicting with the format command.

サインインしてコメントする。

その他の回答 (1 件)

Jannis Korn
Jannis Korn 2021 年 1 月 16 日
Thanks for your answer! I rarely think about predefining the size of my elements, that is indeed a very helpful remark. Also I wasn't aware that such things as
fmt(columns) = {'%f'};
work, so once again thanks for that.
Do you think it would be faster to actually prelocate the entire size of p and then just fill in the values or would the additional code that I'd need to find the line to write in just slow the process?

  1 件のコメント

Walter Roberson
Walter Roberson 2021 年 1 月 16 日
nC = length(Categories);
nP = nC * (nC-1) / 2;
p = zeros(nP, 5);
pidx = 0;
for i= 1:nC-1
sdi = separated_data(:,1:3,i);
for j= i+1:length(Categories)
% separated_data is a 3D array of data, I want to get the p-Values for the data matching
% several numerated categories here
pidx = pidx + 1;
sdj = separated_data(:,1:3,j);
p(pidx,:) = [i, j, ranksum(sdi(:,1),sdj(:,1)), ...
ranksum(sdi(:,2),sdj(:,2)), ranksum(sdi(:,3),sdj(:,3))];
end
end

サインインしてコメントする。

Community Treasure Hunt

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

Start Hunting!

Translated by