How to filter logical column? - matlab

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}]))

Related

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]

Find substring in cell array of numbers and strings

I have a cell array consisting of numbers, strings, and empty arrays. I want to find the position (linear or indexed) of all cells containing a string in which a certain substring of interest appears.
mixedCellArray = {
'adpo' 2134 []
0 [] 'daesad'
'xxxxx' 'dp' 'dpdpd'
}
If the substring of interest is 'dp', then I should get the indices for three cells.
The only solutions I can find work when the cell array contains only strings:
http://www.mathworks.com/matlabcentral/answers/2015-find-index-of-cells-containing-my-string
http://www.mathworks.com/matlabcentral/newsreader/view_thread/255090
One work-around is to find all cells not containing strings, and fill them with '', as hinted by this posting. Unfortunately, my approach requires a variation of that solution, probably something like cellfun('ischar',mixedCellArray). This causes the error:
Error using cellfun
Unknown option.
Thanks for any suggestions on how to figure out the error.
I've posted this to usenet
EDUCATIONAL AFTERNOTE: For those who don't have Matlab at home, and end up bouncing back and forth between Matlab and Octave. I asked above why cellfun doesn't accept 'ischar' as its first argument. The answer turns out to be that the argument must be a function handle in Matlab, so you really need to pass #ischar. There are some functions whose names can be passed as strings, for backward compatibility, but ischar is not one of them.
How about this one-liner:
>> mixedCellArray = {'adpo' 2134 []; 0 [] 'daesad'; 'xxxxx' 'dp' 'dpdpd'};
>> index = cellfun(#(c) ischar(c) && ~isempty(strfind(c, 'dp')), mixedCellArray)
index =
3×3 logical array
1 0 0
0 0 0
0 1 1
You could get by without the ischar(c) && ..., but you will likely want to keep it there since strfind will implicitly convert any numeric values/arrays into their equivalent ASCII characters to do the comparison. That means you could get false positives, as in this example:
>> C = {65, 'A'; 'BAD' [66 65 68]} % Note there's a vector in there
C =
2×2 cell array
[ 65] 'A'
'BAD' [1×3 double]
>> index = cellfun(#(c) ~isempty(strfind(c, 'A')), C) % Removed ischar(c) &&
index =
2×2 logical array
1 1 % They all match!
1 1
Just use a loop, testing with ischar and contains (added in R2016b). The various *funs are basically loops and, in general, do not offer any performance advantage over the explicit loop.
mixedCellArray = {'adpo' 2134 []; 0 [] 'daesad'; 'xxxxx' 'dp' 'dpdpd'};
querystr = 'dp';
test = false(size(mixedCellArray));
for ii = 1:numel(mixedCellArray)
if ischar(mixedCellArray{ii})
test(ii) = contains(mixedCellArray{ii}, querystr);
end
end
Which returns:
test =
3×3 logical array
1 0 0
0 0 0
0 1 1
Edit:
If you don't have a MATLAB version with contains you can substitute a regex:
test(ii) = ~isempty(regexp(mixedCellArray{ii}, querystr, 'once'));
z=cellfun(#(x)strfind(x,'dp'),mixedCellArray,'un',0);
idx=cellfun(#(x)x>0,z,'un',0);
find(~cellfun(#isempty,idx))
Here is a solution from the usenet link in my original post:
>> mixedCellArray = {
'adpo' 2134 []
0 [] 'daesad'
'xxxxx' 'dp' 'dpdpd'
}
mixedCellArray =
'adpo' [2134] []
[ 0] [] 'daesad'
'xxxxx' 'dp' 'dpdpd'
>> ~cellfun( #isempty , ...
cellfun( #(x)strfind(x,'dp') , ...
mixedCellArray , ...
'uniform',0) ...
)
ans =
1 0 0
0 0 0
0 1 1
The inner cellfun is able to apply strfind to even numerical cells because, I presume, Matlab treats numerical arrays and strings the same way. A string is just an array of numbers representing the character codes. The outer cellfun identifies all cells for which the inner cellfun found a match, and the prefix tilde turns that into all cells for which there was NO match.
Thanks to dpb.

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 add rows in between cell array in 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.