I get a cell array which contains 103 cells of different dimensions. Each cell of my cell array represents a matrix and it can be displayed as an image. How can I extract each cell (ie each matrix) in a for loop?
I know how to do that one by one but not for the whole cell :
image1 = cellArray{1}; % extract matrix 1 (on 103) from the cell array #1
image2 = cellArray{2}; % and so on
Thanks for your help
The easiest way to loop through your cell array and apply to same function to every cell is to use cellfun. If your function returns a scalar e.g.
f = #(x)max(:)
then it's as simple as
cellfun(f, cellArray)
Note that f above is an anonymous function (or rather a function handle to an anonymous function), but more likely your function will be in its own m-file in which case you need to use the # operator:
cellfun(#f, cellArray)
Lastly, if your output is not a scalar then call
cellfun(#f, cellArray, 'uni' 0)
Related
I currently have a cell array consisting of 7x1 vectors. I need to extract the first element (1,1) of each vector from each cell and store these values in a new array. This is what I currently have:
for j = 1:numel(xvalues)
cellj = xvalues{j};
a = cellj(1:1);
avalues(1:j) = a;
end
However, I am just generating a cell array with the first element of the last cell, repeating.
How can I fix this?
You can also use cellfun to apply a function to each element in a cell array. So to extract the first element of each vector the following should work.
avalues = cellfun(#(x) x(1),xvalues);
Cellfun loops through each element in the cell array and passes it in to the anonymous function via #(x). We then process x by taking the first element x(1).
In cases such as yours, where the cell contents are matrices of the same size, and assuming your inputs are small enough (meaning that neither memory nor runtime are imminent issues) you can convert the cell array into a numeric matrix and select a vector along the relevant dimension:
function out = q48740494
%% Generate some data:
c = squeeze(num2cell(randi(20,7,1,20),[1,2]));
% c = 20×1 cell array of {7x1 double}
%% Convert this into a numeric array and output:
out = cell2mat(c.'); out = out(1,:);
% BONUS: another version of the line above.
% out = subsref(cell2mat(c.'), substruct('()', {1,1:numel(c)}) ) ;
I have a cell array (2 x 6) called "output", each cell in row #1 {1 -> 6, 2} contains a 1024 x 1024 x 100 matrix. I want to apply movmedian to each cell in row #1. I would like to apply this function in dimension = 3 with window size = 5.
output = cellfun(#movmedian(5,3), output,'uniform', 0);
This is the code that I have come up with so far, however, it produces an "unbalenced or unexpected parenthesis or bracket" error. I am unsure what is causing this error. I am also somewhat unsure how to instruct matlab to perform this operation only on row 1 of the cell array, please help!
Thank you for your time!!
The function handle passed as the first argument to cellfun will be sequentially passed the contents of each cell (i.e. each 3-D matrix). Since you need to also pass the additional parameters needed by movmedian, you should create an anonymous function like so:
#(m) movmedian(m, 5, 3)
Where the input argument m is the 3-D matrix. If you want to apply this to the first row of output, you just have to index the cell array like so:
output(1, :)
This will return a cell array containing the first row of output, with : indicating "all columns". You can use the same index in the assignment if you'd like to store the modified matrices back in the same cells of output.
Putting it all together, here's the solution:
output(1, :) = cellfun(#(m) movmedian(m, 5, 3), output(1, :),...
'UniformOutput', false);
...and a little trick to avoid having to specify 'UniformOutput', false is to encapsulate the results of the anonymous function in a cell array:
output(1, :) = cellfun(#(m) {movmedian(m, 5, 3)}, output(1, :));
I need help to speed up this function I created to remove NaN elements in a cell array.
To explain better my function with an example. Let's suppose we have a cell array of I have a cell array on the form indx{ii} where each ii is an array of size 1xNii (this means the arrays have different size) with NaN elements on it.
datawithNaN{1}=[1,4,8,6];
datawithNaN{2}=[4,6,2];
datawithNaN{3}=[9,8,NaN];
datawithNaN{4}=[3,NaN,NaN];
datawithNaN{5}=[NaN,NaN,NaN,NaN];
What I want the function function to do is remove all NaN elements in the cell array. So the answer for the example should be:
datawithoutNaN{1}=[1,4,8,6];
datawithoutNaN{2}=[4,6,2];
datawithoutNaN{3}=[9,8];
datawithoutNaN{4}=[3];
datawithoutNaN{5}=[];
So far I have written a function that gives me the result I want but it takes too much time specially when working with big cell arrays or big arrays inside the cell array.
My function is:
function result = rmNaN(datawithNaN)
[row_cell, col_cell] = size(datawithNaN);
result = cell(row_cell, col_cell);
for i=1:row_cell
for j=1:col_cell
[row,col]=size(datawithNaN{i,j});
if col>row
datawithNaN{i,j}=datawithNaN{i,j}';
[row,~]=size(datawithNaN{i,j});
end
for k=1:row
if ~isnan(datawithNaN{i,j}(k))
result{i,j}(k) = datawithNaN{i,j}(k);
else
continue
end
end
end
end
You can easily accomplish this with cellfun.
datawithoutNaN = cellfun(#(x)x(~isnan(x)), datawithNaN, 'uniform', 0);
This goes through each element of the cell array, uses isnan to determine which elements in the array are NaN and yields a logical array the same size as x where it is true where it is a NaN and false otherwise. It then negates this and uses it as a logical index to grab only the non-Nan values and return them. The 'uniform' input ensures that the result is also a cell array.
I have a cell array where each cell contains a matrix (different sizes). I would like, e.g., to take all the second columns of the matrices providing a command like:
aux = cArray{:}(:,2)
The result I'd like to obtain is a cell array where each cell contains the second column of the original matrix, but the command doesn't work (and I can even see why, since the output of cArray{:} is not a matrix ... )
Is there a compact command to get what I want instead of a cycle filling up the cell array ?
The reason why it doesn't work is that indexing a cell array with {:} produces a comma-separated list, which is not indexable anymore. You can view it as the "unwrapped" contents of the cell array separated by commas.
You can achieve what you want with cellfun:
result = cellfun(#(x) x(:,2), cArray, 'uniformoutput', false);
This applies the anonymous function #(x) x(:,2) to each cell's contents, and packs the results in a cell array.
In MATLAB, have an N-dimensional cell C, where N is an integer only determined at runtime. How do I access a specific element of C with a vector variable id? For example, with N=3 and id=[1,5,2], how to programmatically get the content of c{1,5,2}? I cannot hard-code it as c{id(1),id(2),id(3)} since N is only fixed at runtime.
If id is a cell array, then you can use sub2ind for this by taking advantage of the comma separated list syntax ,i.e. {:}, to send a variable number of inputs to sub2ind
id = {1,5,2};
ind = sub2ind(size(C), id{:})
c{ind}
if id isn't a cell array (and for some reason can't be created as one), then use num2cell to convert it.