How to add rows in between cell array in Matlab? - matlab

I have two cell arrays.
A(290*6) and B(300*6);
First column in two arrays are identical. I compared first column of two cell arrays using 'ismember'. I want to do that ; where cell elements are missing in cell array(A), I have to add a row where element is missing. Is it possible in Matlab?

It's not easy to insert rows into an existing matrix or cell array; it's easier to construct a new one and fill it appropriately.
Find the locations of the contents of the first column of A in the cell array B:
[aa,bb] = ismember([A{:,1}],[B{:,1}]);
Create a new empty cell array:
C = cell(length(B),size(A,2))
Fill it:
C(:,1)=B(:,1)
C(bb,2:end) = A(aa,2:end);
For example, given this A ("3" row missing)
[1] [3]
[2] [5]
[4] [3]
And this B:
[1]
[2]
[3]
[4]
This returns:
[1] [3]
[2] [5]
[3] []
[4] [3]
To fill the empty spaces with the previous row (this will only work if the empty rows are non-consecutive and the first row of C is non-empty):
n = setdiff(1:length(C),bb)
C(n,2:end) = C(n-1,2:end);

I think you can directly use the second output of setdiff
[d,i] = setdiff(B(:,1),A(:,1))
i will tell you where the rows in A are that are missing.

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.

How to create a sub-cell from a cell array in Matlab?

Lets say I have following cell array data in Matlab:
>> data = {'first', 1; 'second', 2; 'third', 3}
data =
'first' [1]
'second' [2]
'third' [3]
Then I want to create a new cell array which has only the first column data. I tried the following but got only the first value instead.
>> column_1 = data{:,1}
column_1 =
first
But what I would like to get as output is:
>> column_1 = {'first';'second';'third'}
column_1 =
'first'
'second'
'third'
How can I create a sub-cell from first column of data cell array?
You have to use round parentheses indexing instead of curly braces indexing, like this:
data(:,1)
Output:
ans =
3×1 cell array
'first'
'second'
'third'
Basically, the purpose of curly braces is to retrieve the underlying content of cells and present a different behavior. For extracting subsets of cells you need to use round parentheses. For more details, refer to this page of the official Matlab documentation.

getting list of values with list of keys for dictionary in Matlab

Suppose I use containers map to create a dictionary in MATLAB which has the following map:
1-A;
2-B;
3-C;
Denote the dictionary as D.
Now I have an input list [2,1,3], and what I am expecting is [B,A,C]. The problem is, I can't just use [2,1,3] as the input list for D, but only input 2,1 and 3 one by one for D and get B, A, C each time.
This can get the job done but as you can see, it's a bit less efficient.
So my question is: is there anything else I can do to let the dictionary return the whole list at the same time?
As far as I can find there is no one-step solution like python's dict.items. You can, however, get in a few lines. mydict.keys() gives you the keys of the dict as a cell array, and mydict.values() gives you the values as a cell array, so you can (in theory) combine those:
>> mykeys = mydict.keys();
>> myvals = mydict.values();
>> mypairs = [mykeys',myvals']
mypairs =
3×2 cell array
'A' [1]
'B' [2]
'C' [3]
However, in principle maps are unordered, and I can't find anything in the MATLAB documentation that says that the order returns by keys and the order returned by values is necessarily consistent (unlike Python). So if you want to be extra safe, you can call values with a cell array of the keys you want, which in this case would be all the keys:
>> mykeys = mydict.keys();
>> myvals = mydict.values(mykeys);
>> mypairs = [mykeys',myvals']
mypairs =
3×2 cell array
'A' [1]
'B' [2]
'C' [3]

Add a new element to the end of an existing cell array

As the title already mentions, how is it possible to add a new cell array 1x1 at the end of an existing cell array, let's call him Q, which is a cell array 1x3256?
If you mean adding a single cell to the end (i.e. so your 1-by-3256 cell array becomes a 1-by-3257 cell array) then:
Q{end+1} = []
and you can replace [] with your value directly
Alternatively:
Q(end+1) = {[]}
Adding to Dan's answer, in case you have a cell that is not a single dimension cell, you might want to add a full row, for example. In that case, access the cell as an array using ().
>> c = { 1, 'a'; 2, 'b'}
c =
[1] 'a'
[2] 'b'
>> c(end+1,:) = {3,'c'}
c =
[1] 'a'
[2] 'b'
[3] 'c'

How to filter logical column?

I need to get only false value of a logical column, I' ve column data that return this:
K>> data(:,4)
ans =
[1]
[1]
[0]
[0]
[0]
[0]
[0]
I tried this but don't work
data= data(strcmp(data(:,4), {false}), :);
Output:
data =
Empty cell array: 0-by-4
From your data, it appears you want this:
~([data{:,4}])
or maybe this
find(~([data{:,4}]))