find NaN values is cell array - matlab

lets assume I have the following array:
a = {1; 'abc'; NaN}
Now I want to find out in which indices this contains NaN, so that I can replace these with '' (empty string).
If I use cellfun with isnan I get a useless output
cellfun(#isnan, a, 'UniformOutput', false)
ans =
[ 0]
[1x3 logical]
[ 1]
So how would I do this correct?

Indeed, as you found yourself, this can be done by
a(cellfun(#(x) any(isnan(x)),a)) = {''}
Breakdown:
Fx = #(x) any(isnan(x))
will return a logical scalar, irrespective of whether x is a scalar or vector.
Using this function inside cellfun will then erradicate the need for 'UniformOutput', false:
>> inds = cellfun(Fx,a)
inds =
0
0
1
These can be used as indices to the original array:
>> a(inds)
ans =
[NaN]
which in turn allows assignment to these indices:
>> a(inds) = {''}
a =
[1]
'abc'
''
Note that the assignment must be done to a cell array itself. If you don't understand this, read up on the differences between a(inds) and a{inds}.

I found the answer on http://www.mathworks.com/matlabcentral/answers/42273
a(cellfun(#(x) any(isnan(x)),a)) = {''}
However, I do not understant it...

a(ind) = [] will remove the entries from the array
a(ind)= {''} will replace the NaN with an empty string.
If you want to delete the entry use = [] instead of = {''}.
If you wanted to replace the NaNs with a different value just set it equal to that value using curly braces:
a(ind) = {value}

Related

How to convert the string 'pi' to double? (MATLAB 2015a)

When I try to convert the string 'pi' to a double it gets converted to NaN.
>> str2double('pi')
ans =
NaN
I'm reading a file that contains comma separated values, which might include a multiple of pi. For example (assume pi_in_string was read from a file):
>> pi_in_string = '0,1,-pi/6'
pi_in_string =
0,1,-pi/6
>> split_string = strsplit(pi_in_string, ',')
split_string =
'0' '1' '-pi/6'
>> str2double(split_string)
ans =
0 1 NaN
I figured out that I need to use str2num instead of str2double, but str2num doesn't work on a cell array. So instead, I looped through the elements in the cell array, converting each to type char first, then using str2num.
pi_in_string = '0,1,-pi/6';
str_array = strsplit(pi_in_string, ','); %str_array now cell array
num_elements = length(str_array); %get # elements to loop
num_vector = zeros(1,num_elements); %initialize vector
%loop through elements in str_array
for i = 1:num_elements %converting each element first to type char
num_vector(i) = str2num(char(str_array(i)));
end
It is easy to avoid the for loop and explicitly initializing the num_vector array using the cellfun command:
pi_in_string = '0,1,-pi/6';
str_array = strsplit(pi_in_string, ',');
num_vector = cellfun(#(x)eval(x), str_array, 'UniformOutput', true)
num_vector =
0 1.0000 -0.5236

Behavior of 'subsref' for arrays of objects

Imagine a simple array of structures, say:
A = struct('x', {1 2 3}, 'y', {'a' 'b' 'c'});
Asking for a given property for all this array's elements will give something like:
>> A.x
ans =
1
ans =
2
ans =
3
Now, if I explicitly call the subsref function directly on this array, it only retrieves the first element's property:
>> builtin('subsref', A, substruct('.', 'x'))
ans =
1
Why? And is there a possibility to call explicitly another built-in method that will retrieve the property for all the array's elements?
The subsref method can return it but not as a comma separated list the way you get it in the interpreter. It returns them as separate output arguments that means:
>> [a,b,c]=builtin('subsref', A(:), substruct('.', 'x'))
a =
1
b =
2
c =
3
you can capture the output in a cell array if you like
>> [x{1:numel(A)}]=builtin('subsref', A(:), substruct('.', 'x'))
x =
[1] [2] [3]

Matching cell arrays in MATLAB

I am trying to find indices of the elements in one cell array in another cell array in MATLAB. For example:
a = {'Hello', 'Good', 'Sun', 'Moon'};
b = {'Well', 'I', 'You', 'Hello', 'Alone', 'Party', 'Long', 'Moon'};
I expect to get the following result which shows the index of elements of $a$ in array $b$:
index=[4, NaN, NaN, 8];
I know it is possible to implement it using loops, but I think there is simple way to do that which I don't know.
Thanks.
With ismember -
[matches,index] = ismember(a,b)
index(~matches) = nan
With intersect -
[~,pos,idx] = intersect(a,b)
index = nan(1,numel(a))
index(pos) = idx
You could use ismember
[flag,index] = ismember ( a, b )
you can use the 2nd output argument of ismember:
[ida,idb]=ismember(a, b)
ida = 1 0 0 1
idb= 4 0 0 8
If you really need NaN just do:
idb( idb == 0 ) = NaN

MATLAB: strmatch vs strcmp

If I'm using a char string as the needle and a cell array of chars as the haysack, would the following achieve the same results every time? I'm looking at their documentations, but I don't see anything that would suggest otherwise. I wanted to check with SO's community as well.
Basically,
k = strmatch('abc', cellArray, 'exact');
k2 = find(strcmp('abc', cellArray));
where cellArray is an Nx1 cell array of chars and it has 'abc' values at arbitrary indices. For example, if cellArray has abc at indices 10, 20, and 30. Then would the following be true everytime for any cellArray?
k = [10 20 30];
k2 = [10 20 30];
Also, if both methods return the same answers, when would you use strmatch over strcmp in this kind of search scenario (looking for a char string in a cell array of same data type)? strmatch is extremely slow, if anyone is wondering why I'm even asking.
No, the results will be different. The function strmatch returns a vector of indexes where the cell array (haystack) matches the string (needle):
>> arr = {'a', 'b', 'c', 'a', 'b'};
>> strmatch('a', arr, 'exact')
ans =
1
4
The strcmp function returns a logical vector, with 1s where the haystack matches and 0s where it doesn't match:
>> strcmp('a', arr)
ans =
1 0 0 1 0
On the other hand, the expression find(strcmp('a', arr)) is equivalent to strmatch('a', arr, 'exact').
strmatch is not recommended. Use strncmp or validatestring instead. strmatch will be removed from a future version of matlab.
*Warning given in Matlab 2017 a.

prepend a list to a matrix in matlab

i wanted to ask this:
If i have this matrix:
magnetT=NaN(Maxstep,2);
and want to prepend to it the "{0 1}"
how can i write it?
Also,if i have this in mathematica in a loop:
magnetT[[i]] = {T, Apply[Plus, Flatten[mlat]]/L2}
the equivalent in matlab isn't this???
magnetT(i,2)=[T ,sum(mlat(:))./L2];
because it gives me :Subscripted assignment dimension mismatch.
Error in ==> metropolis at 128
magnetT(i,2)=[T,sum(mlat(:))./L2];
Thanks
I'll attempt to answer your first question both questions.
You asked about prepending the NaN array to {0,1} which is a cell array. Any data objects can be readily bundled into a cell array:
>> anyData = NaN(3, 2);
>> newCellArray = {anyData; {0, 1}}
newCellArray =
[3x2 double]
{1x2 cell }
If you are instead trying to concatenate the results into a numeric matrix, the following will help:
>> Maxstep=3;
>> magnetT=NaN(Maxstep,2);
>> newArray = [magnetT; 0 1]
newArray =
NaN NaN
NaN NaN
NaN NaN
0 1
For your second question, MATLAB is complaining about trying to store a vector in one element of magnetT. When computing:
magnetT(i,2)=[T ,sum(mlat(:))./L2];
the right-hand side will create a vector while the left-hand side is trying to store that vector where a scalar is expected. I don't know exactly what you're trying to achieve and I'm not very familiar with Mathematica syntax but perhaps you need to do this instead:
magnetT(ii,:) = [T sum(mlat(:))./L2];
or, in other words:
magnetT(ii,1) = T;
magnetT(ii,2) = sum(mlat(:)) ./ L2;