How to remove a particular set of cells from a cell array? - matlab

Suppose I have an array with 10 cells: C{1},C{2},...,C{10}, and let b=[1 2 8], then I want to empty C{1}, C{2} and C{8}, so I tried C{b}=[], but it does't work. Is there any easy way to do it?

C(b) = [] will do it. The {} notation is for addressing the contents of a cell rather than the cell as a member of the array. If you get more than one cell back from the {} notation it returns as a comma separated list which you can't use for indexing. The () notation will get you an index to the actual cells themselves and is thus the correct way to do this.

Related

How to empty a cell

I have a cell array that contains a lot of NaN. But for whatever reason the isnan function can't detect them (hence this doesn't work cellfun(#(Iarray) any(isnan(Iarray)),Iarray);) so I figured it was actually strings that contains NaN.
I perform two things on this array : cleaning empty rows and columns and removing NaN (well trying to).
So I want to replace all the NaN by empty cells and then perform to clean all empty cells with the isempty function. I'll use a loop and if char(x(i,j))=='NaN'.
So here comes my problem I want to empty a cell and then detect that cell with the isempty function but I have no idea how. I have tried x(1,2)= [], x(1,2)= {[]}, x(1,2)='' but none of those gives a 1 for isempty(x(1,2)) for example.
Does anyone know how to solve my problem?
Thanks in advance!
If you want to empty the content of a cell you can use :
x{1,2} = [];
There is a difference between indexing using parentheses () and brackets {}. You can think a cell array as an array of cells that each cell contains a value such as 1 ,2 , []. When a cell is indexed with parentheses it returns the result as cell (or more precisely as an array of type cell) but when it is indexed with brackets it returns the content of the cell (or more precisely as a comma separated list containing the contents of the indexed cells). So when you write such an expression:
x(1,2) = [];
It removes the second element from the array of cells and behaves like indexing other array types. For example when you want to remove the second element of a = [1 2 3] you can use a(2)=[].
But when you write x{1,2} = []; it accesses the content of the cell and sets it to a null array [0 x 0] of type double that is empty.
Likewise a={} is a [0 x 0] null array of cells and b={[]} is an [1 x 1] array of cells that its first element contains a null array [0 x 0] of type double. When you use isempty(b) it returns false because it contains an element and when you use isempty(b(1)) it returns false because b(1) returns an array of cells that contains an element but when you use isempty(b{1}) it returns true because the {} operator extracts the contents of the first cell that is a null array.
In short, cells can be accessed using both () and {}, and based on the situation [] has different functionalities: a) removing element b) null array.

Convert cell array with sub cells into numeric array

Assume I have A that is a 64x1 cell array.
Each of the 64 cells contains another cell with a string (which is a number, i.e. 11)
A{1, 1}{1, 1} = ’11’ (char)
A{2, 1}{1, 1} = ’13’ (char)
How can I create a numeric array such as
A = [11,13,…]
The cell2mat function seems to work only on “first level” cell array:
cell2mat does not support cell arrays containing cell arrays or objects.
You can use cellfun to convert the contents of each individual cell in A to doubles.
A{1, 1}{1, 1} = '11';
A{2, 1}{1, 1} = '13';
A_array = cellfun(#(a) str2double(a), A)
Breakdown of the function: #(a) passes the contents of each cell of A to the variable a, which can be converted to doubles using str2double(a).
It's quite simple, however you need split it to two steps. Let's assume we have simple 1x4 string array:
A= {'11','13','15','17'};
To convert it you need store the content in temporary variable S, then use sscanf to generate final result:
S = sprintf('%s ', A{:});
Result = sscanf(S, '%f')
The only problem is that it will be column vector. If you need it in a row, you can just transpose(Results).
I'm not sure I entirely understand your question. If I've got it right, you're talking about a cell array like asd below
asd=cell(61,1);
for ii=1:64
asd{ii}={['test',num2str(ii)]}
end
If I understand your goal correctly, I think the following does it somewhat neatly
A=char([asd{:}])
Then if you want to convert the strings to numbers (which wouldn't work for my test, but might for your strings), just use str2num on this new vector
Transform A into a comma-separated list of cells, then horizontally concatenate these cells and finally apply str2double;
A = str2double([A{:}]);

Difference between accessing cell elements using curly braces and parentheses

What is the difference between accessing elements in a cell array using parentheses () and curly braces {}?
For example, I tried to use cell{4} = [] and cell(4) = []. In the first case it sets the 4th element to [], but in the second case it wiped out the cell element, that is, reduced the cell element count by 1.
Think of cell array as a regular homogenic array, whose elements are all cells. Parentheses (()) simply access the cell wrapper object, while accessing elements using curly bracers ({}) gives the actual object contained within the cell.
For example,
A={ [5,6], 0 , 0 ,0 };
Will look like this:
The syntax of making an element equal to [] with parentheses is actually a request to delete that element, so when you ask to do foo(i) = [] you remove the i-th cell. It is not an assignment operation, but rather a RemoveElement operation, which uses similar syntax to assignment.
However, when you do foo{i} = [] you are assigning to the i-th cell a new value (which is an empty array), thus clearing the contents of that cell.
See the help in this link. As you'll see, accessing with parentheses (), gives you a subset of a cell (i.e. a sub-cell), while curly braces {} gives you the content of the cell you are trying to access.

If a MATLAB function returns a variable number of values, how can I get all of them as a cell array?

I am writing a function to remove some values from a cell array, like so:
function left = remove(cells, item);
left = cells{cellfun(#(i) ~isequal(item, i), cells)};
But when I run this, left has only the first value, as the call to cells{} with a logical array returns all of the matching cells as separate values. How do I group these separate return values into a single cell array?
Also, perhaps there is already a way to remove a given item from a cell array? I could not find it in the documentation.
You have to use () instead of {} to index the cells:
function left = remove(cells, item)
left = cells(cellfun(#(i) ~isequal(item, i), cells));
Using () for indexing will give you a subset of cells, while using {} will return the contents of a subset of cells as a comma-separated list, and only the first entry of that list will get placed in left in your example.
You can check out this MATLAB documentation for more information on using cell arrays.
EDIT: Response to comment...
If you have an operation that ends up giving you a comma-separated list, you can place the individual elements of the list into cells of a cell array by surrounding the operation with curly braces. For your example, you could do:
left = {cells{cellfun(#(i) ~isequal(item, i), cells)}};
The inner set of curly braces creates a comma-separated list of the contents of cells that are not equal to item, and the outer set then collects this list into a cell array. This will, of course, give the same result as just using parentheses for the indexing, which is the more sensible approach in this case.
If you have a function that returns multiple output arguments, and you want to collect these multiple values into a cell array, then it's a bit more complicated. You first have to decide how many output arguments you will get, or you can use the function NARGOUT to get all possible outputs:
nOut = 3; %# Get the first three output arguments
%# Or...
nOut = nargout(#some_fcn); %# Get all the output arguments from some_fcn
Then you can collect the outputs into a 1-by-nOut cell array outArgs by doing the following:
[outArgs{1:nOut}] = some_fcn(...);
It should be noted that NARGOUT will return a negative value if the function has a variable number of output arguments, so you will have to choose the value for nOut yourself in such a case.

Iterating through struct fieldnames in MATLAB

My question is easily summarized as: "Why does the following not work?"
teststruct = struct('a',3,'b',5,'c',9)
fields = fieldnames(teststruct)
for i=1:numel(fields)
fields(i)
teststruct.(fields(i))
end
output:
ans = 'a'
??? Argument to dynamic structure reference must evaluate to a valid field name.
Especially since teststruct.('a') does work. And fields(i) prints out ans = 'a'.
I can't get my head around it.
You have to use curly braces ({}) to access fields, since the fieldnames function returns a cell array of strings:
for i = 1:numel(fields)
teststruct.(fields{i})
end
Using parentheses to access data in your cell array will just return another cell array, which is displayed differently from a character array:
>> fields(1) % Get the first cell of the cell array
ans =
'a' % This is how the 1-element cell array is displayed
>> fields{1} % Get the contents of the first cell of the cell array
ans =
a % This is how the single character is displayed
Since fields or fns are cell arrays, you have to index with curly brackets {} in order to access the contents of the cell, i.e. the string.
Note that instead of looping over a number, you can also loop over fields directly, making use of a neat Matlab features that lets you loop through any array. The iteration variable takes on the value of each column of the array.
teststruct = struct('a',3,'b',5,'c',9)
fields = fieldnames(teststruct)
for fn=fields'
fn
%# since fn is a 1-by-1 cell array, you still need to index into it, unfortunately
teststruct.(fn{1})
end
Your fns is a cellstr array. You need to index in to it with {} instead of () to get the single string out as char.
fns{i}
teststruct.(fns{i})
Indexing in to it with () returns a 1-long cellstr array, which isn't the same format as the char array that the ".(name)" dynamic field reference wants. The formatting, especially in the display output, can be confusing. To see the difference, try this.
name_as_char = 'a'
name_as_cellstr = {'a'}
You can use the for each toolbox from http://www.mathworks.com/matlabcentral/fileexchange/48729-for-each.
>> signal
signal =
sin: {{1x1x25 cell} {1x1x25 cell}}
cos: {{1x1x25 cell} {1x1x25 cell}}
>> each(fieldnames(signal))
ans =
CellIterator with properties:
NumberOfIterations: 2.0000e+000
Usage:
for bridge = each(fieldnames(signal))
signal.(bridge) = rand(10);
end
I like it very much. Credit of course go to Jeremy Hughes who developed the toolbox.