Use arrayfun and cellfun to avoid for-loops

8 visualizaciones (últimos 30 días)
Jannis Korn
Jannis Korn el 16 de En. de 2021
Comentada: Walter Roberson el 16 de En. de 2021
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!

Respuesta aceptada

Walter Roberson
Walter Roberson el 16 de En. de 2021
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 comentario
Walter Roberson
Walter Roberson el 16 de En. de 2021
Editada: Walter Roberson el 16 de En. de 2021
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.

Iniciar sesión para comentar.

Más respuestas (1)

Jannis Korn
Jannis Korn el 16 de En. de 2021
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 comentario
Walter Roberson
Walter Roberson el 16 de En. de 2021
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

Iniciar sesión para comentar.

Categorías

Más información sobre Matrix Indexing en Help Center y File Exchange.

Productos


Versión

R2020b

Community Treasure Hunt

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

Start Hunting!

Translated by