How to remove rows from cell array based on multiple conditions?

I would like to separate the following sample array into 2 arrays. If C contains any of the following strings (red, spoon, fork) within the row, I want to remove the row and put it into a new cell array.
clear all
clc
% Sample cell array
C = [{'A1';'A3';'A4';'A7'},{'blue';'green';'red';'blue'},{'spoon';'fork';'knife';'cup'},num2cell(rand(4,1))];
idx = cellfun(@(x) strcmp(x, 'red', 'spoon','fork'), C(:,:));
% Extracted data
C1 = C(idx,:);
% Others
C2 = C(~idx,:);
new arrays should look like...
C1 =
'A1' 'blue' 'spoon' [0.6948]
'A3' 'green' 'fork' [0.3171]
'A4' 'red' 'knife' [0.9502]
C2 =
'A7' 'blue' 'cup' [0.0344]

 Respuesta aceptada

James Tursa
James Tursa el 15 de Jul. de 2017
Editada: James Tursa el 15 de Jul. de 2017
E.g., assuming your columns are nice and are not mixed class:
C = your cell array
S = your cell string compare array, e.g., {'red', 'spoon','fork'}
x = cellfun(@ischar,C);
Cx = reshape(C(x),size(C,1),[]);
y = any(ismember(Cx,S),2);
C1 = C(y,:);
C2 = C(~y,:);

7 comentarios

They are mixed classes and ideally I don't want to convert the numeric values to characters because I need to sum them later. Would that require any changes to the solution?
James Tursa
James Tursa el 15 de Jul. de 2017
Editada: James Tursa el 15 de Jul. de 2017
So, anything could be in any cell element? The char strings could be randomly mixed in with numeric data anywhere? There is no ordering by column as your example shows?
Calabrese
Calabrese el 15 de Jul. de 2017
Editada: Calabrese el 15 de Jul. de 2017
Columns 1, 2, and 3 are all character strings and column 4 is always numeric.
I didn't realize how much of a difference that would make or I would have specified in my original question. I modified my cell arrays in the question to reflect my needs more specifically.
James Tursa
James Tursa el 15 de Jul. de 2017
Editada: James Tursa el 15 de Jul. de 2017
The solution I posted should work as long as each column is either completely char or completely non-char. It doesn't matter where these columns are. E.g., either your original example or your current example is fine. What would not work is if there were char strings and numeric data in the same column. For that case, my posted code would need to be altered (e.g., by looping over the rows).
Calabrese
Calabrese el 15 de Jul. de 2017
Editada: Calabrese el 15 de Jul. de 2017
It works great for the example array, however when I apply it to the large array I am working with I get an error using reshape. Not all of my numeric values have the same character length. From what I read, I think that is causing the issue. Sometimes there is a NaN as well in the array, the NaN will always exist under columns 1, 2, and 3. i.e.
C =
'A1' 'blue' 'spoon' [0.6948]
'A3' NaN 'fork' [14.3171]
'A4' 'red' 'knife' [1.9502]
'A7' 'blue' 'cup' [11.0344]
If the numeric character length is the issue, it wouldn't be a problem reducing the numeric values to..
[0.6948]
[14.317]
[1.9502]
[11.034]
OK, since your columns can have mixed data type, I have converted my code to loop over the rows:
m = size(C,1);
y = true(m,1);
for k=1:m
x = cellfun(@ischar,C(k,:));
y(k) = any(ismember(C(k,x),S));
end
C1 = C(y,:);
C2 = C(~y,:);
This is extremely helpful, thank you!

Iniciar sesión para comentar.

Más respuestas (0)

Categorías

Preguntada:

el 15 de Jul. de 2017

Comentada:

el 15 de Jul. de 2017

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by