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.
Related
For example I have a 1x5 string array. Now I saw some fields are []. What does this mean? And what is the difference between a field which is totally empty?
How can I create such fields?
array(1)=[];
array(2)=;
%or
array(3)="";
And how can I check if the input of a field is empty, NaN or ""?
array(1)=[]; means that you're removing the first element of array if the variable already exists.
array(2)=; is an invalid expression.
array(3)="" stores an empty string "" at the third index of array. Since first two indices were not initialized by you in your code snippet, so these two indices will store <missing>. If you had an array of double class, you would have got zeros instead of <missing>. Presence of <missing> can be checked by ismissing.
In a string array, you cannot have Nan or empty. You can have "" string though.
You can have those elements if you have a cell array instead.
array{1} = [];
array{2} = "";
array{3} = NaN;
Now presence of [], "", and NaN in the above cell array can be checked by isempty, strcmp and isnan respectively with cellfun.
I'm a bit new to the matlab world, and I'm running into an issue that I'm sure has an easy solution.
I've imported some data from a text file and parsed out the headers, which resulted in a 1x35 cell called Data. In each cell (for example Data{1,1,1}) is data that looks like:
'600000 -947.772827 -107.045776 -70.818062'
'600001 -920.431396 -86.098122 -56.485119'
'600002 -878.332886 -88.673630 -85.249130'
'600003 -851.637695 -68.546539 -96.691711'
'600004 -834.707642 -28.951260 -73.218872'
'600005 -783.431580 40.657402 24.242268'
The problem is, each line is contained in a single column. I'd like to parse it out so that I have 4 columns instead of one.
I tried parsing out the Data cell even further using:
textscan(Data{1,1,1}, '%u%f10%f10%f10', 1)
But it resulted in the following error:
Error using textscan
First input must be of type double or string.
Can I use textscan this way, or do I need to use some other method to break out the text?
With textscan, you can only specify a single string or a single number. With your input, I suspect it is a 6 x 1 cell array of strings. As such, you have no choice but to iterate over each cell and convert each cell array contents with textscan Also, get rid of the %10 spacing as it's actually screwing up where you're parsing out the string. Also, set the identifier to identify the first number you see to double (%f) as opposed to unsigned integer (%u) to allow for easier conversion.
Therefore, do something like this:
>> Data{1,1,1} = {'600000 -947.772827 -107.045776 -70.818062'
'600001 -920.431396 -86.098122 -56.485119'
'600002 -878.332886 -88.673630 -85.249130'
'600003 -851.637695 -68.546539 -96.691711'
'600004 -834.707642 -28.951260 -73.218872'
'600005 -783.431580 40.657402 24.242268'};
>> format long g;
>> vals = cell2mat(cellfun(#(x) cell2mat(textscan(x, '%f%f%f%f', 1)), Data{1,1,1}, 'uni', 0))
vals =
Columns 1 through 3
600000 -947.772827 -107.045776
600001 -920.431396 -86.098122
600002 -878.332886 -88.67363
600003 -851.637695 -68.546539
600004 -834.707642 -28.95126
600005 -783.43158 40.657402
Column 4
-70.818062
-56.485119
-85.24913
-96.691711
-73.218872
24.242268
That statement vals = ... is quite a mouthful, but easy to explain. Start with this statement:
cell2mat(textscan(x, '%f%f%f%f', 1))
For a given cell x in Data{1,1,1}, we want to parse out four numbers for each string that is stored in x. textscan will place these numbers as individual cell elements into a cell array. We want to convert each element into a numeric array, and so cell2mat is required for us to do so.
In order to operate over all of the elements in Data{1,1,1}, we need to use cellfun to allow us to do so:
cellfun(#(x) cell2mat(textscan(x, '%f%f%f%f', 1)), Data{1,1,1}, 'uni', 0)
The first input is a function that operates on each cell stored in Data{1,1,1} (the second input). We are basically telling cellfun that we want to operate on each cell in the cell array stored in Data{1,1,1} in the way I talked about before. This function has input parameter x, which is one cell from Data{1,1,1}. Now, the uni flag is set to 0 because the output of cellfun will not be a single number, but an array of numbers - one array per line that you have in your cell array. The output of this stage would be a 6 element cell array where each location is a 4 element numeric array. To finish it off, we call cell2mat on this output to finally convert our text into a 2D matrix and therefore:
vals = cell2mat(cellfun(#(x) cell2mat(textscan(x, '%f%f%f%f', 1)), Data{1,1,1}, 'uni', 0))
format long g allows for better display formatting so we can see both the dominant number as well as the floating point numbers neatly.
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.
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.
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.