When and why should I use cellfun in Matlab?

I have a question regarding the cellfun function in MATLAB.

When / why should I use it, and when can I also remove it?

A simple example: let them say that I have cell a , and I want to find the average value of all the values ​​in a .

 a{1} = [1 2;3 4]; a{2} = [1 2 3;4 5 6; 7 8 9]; 

My approach would be something like this:

 mean([a{1}(:); a{2}(:)]) 

What would be the appropriate version of cellfun this, and is it better?

I tried doing something like this (obviously not working):

 mean_a = mean(cellfun(@mean, a,'UniformOutput',0)) 

Thanks!

+4
source share
4 answers

cellfun is like a loop through a matrix of cells and
execution of the specified function separately for each cell.
This is usually faster than doing the same thing right in the loop, but the main difference is that it is easy to use to write and read - it’s immediately clear what a call does. But you could also write a loop yourself.

In your specific case, you can use cellfun as follows:

 mean_a = mean(cellfun(@(x) mean(x(:)), a)); 

If you have thousands of cells and you want to do something for each of them, you either use a loop or cellfun
BTW: @(x) means that you want the contents of each cell to be understood as x , so mean(x(:)) gives you what you want - the average of the entire contents of the matrix in the cell.

+3
source

Of course, it depends on what you want to do. cellfun designed for independent work on each cell in an array of cells. If you want to assign a global value to the cell array values ​​and insist on using cellfun , then this should work:

 mean_a = mean(cell2mat(cellfun(@mean, a,'UniformOutput',0))) 
+4
source

Based on your attempt at a solution, I believe that answering them will help solve your problem. However, it seems to me that your decision will weigh some values ​​more than others, and may not be valuable to all readers.
Using your matrices,

 mean([a{1}(:); a{2}(:)]) ~= mean([mean(a{1}(:)) mean(a{2}(:))]) 4.2308 ~= 3.75 

This is the case when numel (a {1}) ~ = numel (a {2}).

The decision made is equivalent to the right side of the equation, but the original implementation is (obviously) equal to the left side. Anyone can be right, given your needs.

For balance, I suggest one (of many) ways to perform a weightless average of all the elements of your cell by changing each matrix to an array of columns and combining them:

 b = cellfun(@(x) reshape(x, 1, []), a, 'UniformOutput', false); mean_a = mean([b{:}]) 
+2
source

I like to use cellfun to build operations instead of loops, for example, if I have several sets of sensor data and each set has several columns (due to the many sensors in the set), this is very convenient using

 numOfSensors = 5; numOfSets = 6; %% sample data preparation x = 1:100; y = rand(length(x), numOfSets*numOfSensors); yCell = mat2cell(y, 100, numOfSensors*ones(1,numOfSets)); % this is my sensor data scaleCell = num2cell(fliplr(cumsum(1:numOfSets))); yCell = cellfun(@(x, scale)x.*scale, yCell, scaleCell, 'unif', false); %% plot preparation nameCell = arrayfun(@(x)['sensor set ' num2str(x)], 1:numOfSets, 'unif', false); colorCell = num2cell(lines(numOfSets), 2)'; %% plot figure, hold all, set(gca, 'ColorOrder', [0 0 0], 'LineStyleOrder', {'-','--','-*','-.',':'}) h = cellfun(@(y, name, c)plot(x, y, 'linewidth', 1.5, 'displayName', name, 'color', c), yCell, nameCell, colorCell, 'unif', false); hh = cellfun(@(x)x(1), h, 'unif', false); legend([hh{:}]) 

instead of a loop. In this example, all data sets are presented, each data set in it has its own color and each sensor is on one data set with another linestyle. The legend is displayed only for each data set (note: this can also be done using hggroups).

Or a simpler use case - I again have an array of data cells and want to have a short view in it:

 figure, hold all, cellfun(@plot,dataCell) 

What is it, one line, very fast on the command line.

Another great use case is to compress large-sized numeric data using averages (), max (), min (), std (), etc., but you already mentioned that. This becomes even more important if the data does not have the same size.

0
source

Source: https://habr.com/ru/post/1481025/


All Articles