How to manipulate a cell array

4 vues (au cours des 30 derniers jours)
grima gandolf
grima gandolf le 13 Déc 2015
Modifié(e) : Guillaume le 18 Déc 2015
Dear Matlab Community,
Well, the truth is that I am a newbie in Matlab and conconfrontated with a (simple) problem.
I have created the following cell
Cell = transpose({1, 2, 3, 'func1(4545, 4545, 3222)', 'func2(111,222)', 7, 8, 9});
which looks like this
[ 1]
[ 2]
[ 3]
'func1(4545, 4545, 3222)'
'func2(111,222)'
[ 7]
[ 8]
[ 9]
Next thing I did was looking for cell entries which are non-numeric by
CellsInd = cellfun(@(x) isnumeric(x), Cells, 'UniformOutput', true);
while in the next step non-numeric cell entries are splited by
Cells(~CellsInd, 1) = regexp(Cells(~CellsInd, 1), '\(|,|\)', 'split');
to get
[ 1]
[ 2]
[ 3]
{1x5 cell}
{1x4 cell}
[ 7]
[ 8]
[ 9]
So far it works. What I want to have is the following structure
[ 1] [ ] [ ] [ ]
[ 2] [ ] [ ] [ ]
[ 3] [ ] [ ] [ ]
[-1] [4545] [4545] [3222]
[-2] [ 111] [ 222] [ ]
[ 7] [ ] [ ] [ ]
[ 8] [ ] [ ] [ ]
[ 9] [ ] [ ] [ ]
i.e. func1 should be replaced by -1, and func2 by -2. Moreover the {1x5 cell} and {1x4 cell} contains an empty cell due to regexp.
How to get rid of this (simple) problem?
Thank you for your reading and effort.
Best wishes gimlii

Réponses (1)

Guillaume
Guillaume le 13 Déc 2015
First, note that while your code works, conceptually, there is a bug. The splitting of the non-numeric entries should read:
Cells(~CellsInd) = regexp(Cells(~CellsInd), '\(|,|\)', 'split'); %CellsInd is already the same shape as Cells
Your original code works, because you start with a vector cell array, but try it with:
c = {1, 2, '3'; '4', 5, 6}; %by the way naming a variable Cell or Cells is a bad idea. Too close to the cell function.
and you'll see it fails.
Anyway, one way to expand your cell array:
c = {1, 2, 3, 'func1(4545, 4545, 3222)', 'func2(111,222)', 7, 8, 9}';
numericcells = cellfun(@isnumeric, c); %simpler syntax than yours. Also, 'UniformOutput, true is default.
c(~numericcells) = regexp(c(~numericcells), '\(|,|\)', 'split');
maxcols = max(cellfun(@numel, c));
c2 = cell(size(c, 1), maxcols); %destination
c2(numericcells, 1) = c(numericcells); %note the numericcells, 1 is intended for c2
textrows = cellfun(@(x) [x, cell(1, maxcols-numel(x))], c(~numericcells), 'UniformOutput', false); %expand text rows to the same number of columns
c2(~numericcells, :) = vertcat(textrows{:})
Finally, to remove columns with all empty:
c2(:, all(cellfun(@isempty, c2))) = []
  6 commentaires
Guillaume
Guillaume le 18 Déc 2015
Modifié(e) : Guillaume le 18 Déc 2015
Please use comments, rather than answers. Original comment by grima gandolf, posted as an answer moved here:
Dear Guillaume, Thank you for your effort and help.
Indeed, there is one fact, which I don't considered yet. Well, it happens sometimes that the cell array have the following structure
[ 1]
[ 2]
[ 3]
'asdasd(4545, 4545, 3222)'
'wrfsdfs(111,222)'
'wrfsdfs(41, 311)'
'asdasd(33,55)'
[ 7]
[ 8]
[ 9]
where some rows contain the same string, i.e., 'asdasd' or 'wrfsdfs'. Thus, for my purposes, it is very important that 'asdasd' is always replaced by [-1] and 'wrfsdfs' by [-2], in such a way that
[ 1] [ ] [ ] [ ]
[ 2] [ ] [ ] [ ]
[ 3] [ ] [ ] [ ]
[-1] [4545] [4545] [3222]
[-2] [ 111] [ 222] [ ]
[-2] [ 41] [ 311] [ ]
[-1] [ 33] [ 55] [ ]
[ 7] [ ] [ ] [ ]
[ 8] [ ] [ ] [ ]
[ 9] [ ] [ ] [ ]
is obtained. Do you think, that strrep() is a good choice to do it?
Cheers, gimlii
Guillaume
Guillaume le 18 Déc 2015
Modifié(e) : Guillaume le 18 Déc 2015
No strrep is never a good choice. You're replacing strings by numbers, strrep is only useful to replace part of a string by another string.
I think that you need to spend more time trying to understand how the pieces of code I've posted work and experiment with modifying it yourself. It's the only way you'll gain enough experience to write the same on your own. Otherwise, you're just going to keep coming back asking for more and more refinements.
The code allows you to identify which cells contain text that is not a number, textcells(~numbercells). You can manipulate these cells any way you want and replace them by anything you want according to whatever rule.
If you want to identify unique text and where the repetitions are it's straightforward with matlab: simply use unique.
So, a simple way to do what you want is with:
[~, ~, unidx] = unique(textcells(~numbercells));
textcells(~numbercells) = num2cell(-unidx); %replace non numeric strings with unique indices

Connectez-vous pour commenter.

Catégories

En savoir plus sur Characters and Strings dans Help Center et File Exchange

Community Treasure Hunt

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

Start Hunting!

Translated by