How to delete a specified string value in a nested cell array

12 ビュー (過去 30 日間)
Billy
Billy 2023 年 3 月 17 日
コメント済み: Voss 2023 年 3 月 17 日
I have a cell array which is 3000x1, called 'AOI'. Within this cell array are nested cell arrays, each with a single column but with variable length. For instance, the first cell is 300x1, the second cell is 200x1, etc. Within these nested cells are lists of names describing data. I want to delete all nested cells with the value 'NO AOI' in them, and create a new cell array out of this. Thus, the dimensions of each nested cell array will likely change (decrease in size), and all cells equal to 'NO AOI' are removed. Unfortunately, I'm struggling to execute this code. Can someone help please?
I have tried the following:
for i = 1:numel(AOI)
nested_cell = AOI{i};
idx = strcmp(nested_cell, 'NO AOI');
AOI{i}(idx, :) = [];
end
% Create new cell array
new_AOI = AOI(~cellfun('isempty', AOI));
However, this hasn't worked - new_AOI is simply the same as AOI. Please help!
Thank you so much!

採用された回答

Voss
Voss 2023 年 3 月 17 日
If AOI is a cell array of cell arrays of character vectors, like this:
AOI = {{'AOI 1';'AOI 2';'NO AOI';'AOI 3'}; {'NO AOI';'NO AOI'}; {'AOI 1';'NO AOI';'NO AOI';'AOI 2'}};
AOI{:}
ans = 4×1 cell array
{'AOI 1' } {'AOI 2' } {'NO AOI'} {'AOI 3' }
ans = 2×1 cell array
{'NO AOI'} {'NO AOI'}
ans = 4×1 cell array
{'AOI 1' } {'NO AOI'} {'NO AOI'} {'AOI 2' }
Then the code works:
for i = 1:numel(AOI)
nested_cell = AOI{i};
idx = strcmp(nested_cell, 'NO AOI');
AOI{i}(idx, :) = [];
end
AOI{:}
ans = 3×1 cell array
{'AOI 1'} {'AOI 2'} {'AOI 3'}
ans = 0×1 empty cell array
ans = 2×1 cell array
{'AOI 1'} {'AOI 2'}
% Create new cell array
new_AOI = AOI(~cellfun('isempty', AOI));
new_AOI{:}
ans = 3×1 cell array
{'AOI 1'} {'AOI 2'} {'AOI 3'}
ans = 2×1 cell array
{'AOI 1'} {'AOI 2'}
So I'm guessing you actually have a cell array of cell arrays of strings, like this:
AOI = {{"AOI 1";"AOI 2";"NO AOI";"AOI 3"}; {"NO AOI";"NO AOI"}; {"AOI 1";"NO AOI";"NO AOI";"AOI 2"}};
AOI{:}
ans = 4×1 cell array
{["AOI 1" ]} {["AOI 2" ]} {["NO AOI"]} {["AOI 3" ]}
ans = 2×1 cell array
{["NO AOI"]} {["NO AOI"]}
ans = 4×1 cell array
{["AOI 1" ]} {["NO AOI"]} {["NO AOI"]} {["AOI 2" ]}
If that's the case, you can make an adjustment as follows. [nested_cell{:}] concatenates the contents of nested_cell, in this case producing a string array from the cell array of strings nested_cell, which strcmp works properly on.
for i = 1:numel(AOI)
nested_cell = AOI{i};
idx = strcmp([nested_cell{:}], 'NO AOI');
AOI{i}(idx, :) = [];
end
AOI{:}
ans = 3×1 cell array
{["AOI 1"]} {["AOI 2"]} {["AOI 3"]}
ans = 0×1 empty cell array
ans = 2×1 cell array
{["AOI 1"]} {["AOI 2"]}
% Create new cell array
new_AOI = AOI(~cellfun('isempty', AOI));
new_AOI{:}
ans = 3×1 cell array
{["AOI 1"]} {["AOI 2"]} {["AOI 3"]}
ans = 2×1 cell array
{["AOI 1"]} {["AOI 2"]}
An alternative would be to use cellstr to convert nested_cell to a cell array of character vectors regardless of whether it already was one or whether it was a cell array of strings. This might be useful in case AOI contains mixed types. Something like this:
AOI = {{'AOI 1';"AOI 2";"NO AOI";'AOI 3'}; {"NO AOI";"NO AOI"}; {'AOI 1';'NO AOI';'NO AOI';'AOI 2'}};
AOI{:}
ans = 4×1 cell array
{'AOI 1' } {["AOI 2" ]} {["NO AOI"]} {'AOI 3' }
ans = 2×1 cell array
{["NO AOI"]} {["NO AOI"]}
ans = 4×1 cell array
{'AOI 1' } {'NO AOI'} {'NO AOI'} {'AOI 2' }
for i = 1:numel(AOI)
nested_cell = cellstr(AOI{i});
idx = strcmp(nested_cell, 'NO AOI');
AOI{i}(idx, :) = [];
end
AOI{:}
ans = 3×1 cell array
{'AOI 1' } {["AOI 2"]} {'AOI 3' }
ans = 0×1 empty cell array
ans = 2×1 cell array
{'AOI 1'} {'AOI 2'}
% Create new cell array
new_AOI = AOI(~cellfun('isempty', AOI));
new_AOI{:}
ans = 3×1 cell array
{'AOI 1' } {["AOI 2"]} {'AOI 3' }
ans = 2×1 cell array
{'AOI 1'} {'AOI 2'}
Of course, new_AOI still contains the original contents (some strings, some character vectors) of those elements that were not 'NO AOI' or "NO AOI". If you want to end up with a cell array of cell arrays of only character vectors instead, you can convert AOI first. Something like this:
AOI = {{'AOI 1';"AOI 2";"NO AOI";'AOI 3'}; {"NO AOI";"NO AOI"}; {'AOI 1';'NO AOI';'NO AOI';'AOI 2'}};
AOI{:}
ans = 4×1 cell array
{'AOI 1' } {["AOI 2" ]} {["NO AOI"]} {'AOI 3' }
ans = 2×1 cell array
{["NO AOI"]} {["NO AOI"]}
ans = 4×1 cell array
{'AOI 1' } {'NO AOI'} {'NO AOI'} {'AOI 2' }
AOI = cellfun(@cellstr,AOI,'UniformOutput',false);
AOI{:}
ans = 4×1 cell array
{'AOI 1' } {'AOI 2' } {'NO AOI'} {'AOI 3' }
ans = 2×1 cell array
{'NO AOI'} {'NO AOI'}
ans = 4×1 cell array
{'AOI 1' } {'NO AOI'} {'NO AOI'} {'AOI 2' }
Then use your code as you already have it, since it has been shown to work on a cell array of cell arrays of character vectors at the beginning of this answer. Or rewrite the loop without the temporary variables nested_cell and idx:
for i = 1:numel(AOI)
AOI{i}(strcmp(AOI{i}, 'NO AOI'), :) = [];
end
AOI{:}
ans = 3×1 cell array
{'AOI 1'} {'AOI 2'} {'AOI 3'}
ans = 0×1 empty cell array
ans = 2×1 cell array
{'AOI 1'} {'AOI 2'}
Also, note that you can avoid creating a separate variable new_AOI, and call the result AOI (which has already been modified in the loop - so preserving it is obviously not a concern):
% call the result AOI instead of new_AOI
AOI = AOI(~cellfun(@isempty, AOI)); % (function handle @isempty works the same as character vector 'isempty' in cellfun)
Or you can just operate on AOI directly:
% or, remove empty cell arrays from AOI
AOI(cellfun(@isempty, AOI)) = [];
  4 件のコメント
Billy
Billy 2023 年 3 月 17 日
Actually don't worry, this makes sense! Thanks so much for the help.
Voss
Voss 2023 年 3 月 17 日
You're welcome!

サインインしてコメントする。

その他の回答 (0 件)

カテゴリ

Help Center および File ExchangeStructures についてさらに検索

Community Treasure Hunt

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

Start Hunting!

Translated by