Use arrayfun and cellfun to avoid for-loops

8 ビュー (過去 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!

採用された回答

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 日
編集済み: 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

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

カテゴリ

Help Center および File ExchangeMatrix Indexing についてさらに検索

製品


リリース

R2020b

Community Treasure Hunt

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

Start Hunting!

Translated by