0

I have a large 3D CELL ARRAY (x1) which I have to delete the empty rows. How can I do this?

Example of my cell array (some pieces of the variable):

val(:,:,1) = 

[20]    []    []    []    []    []    []    []
[ 0]    []    []    []    []    []    []    []
[ 0]    []    []    []    []    []    []    []
[]      []    []    []    []    []    []    []

(...)

val(:,:,42) = 


[ 34225]    [   215]    [    0]    [   0]    [    0]    [    0]    [    0]    [    0]
[ 85200]    [   545]    [    0]    [   0]    [    0]    [    0]    [    0]    [    0]
[ 65074]    [   190]    [ 1000]    [   0]    [    0]    [    0]    [    0]    [    0]
[ 81570]    [  1385]    [ 2475]    [   0]    [    0]    [    0]    [    0]    [    0]    
[ 67236]    [   530]    [  365]    [   0]    [    0]    [    0]    [    0]    [    0]
[ 61338]    [     0]    [  100]    [   0]    [    0]    [    0]    [    0]    [    0]
[]          []          []         []        []         []         []         []    
[]          []          []         []        []         []         []         []  
[]          []          []         []        []         []         []         []   

In this case, I want to exclude the 4th row of (:,:,1), the three last rows from (:,:,42) and all the others from these variable.

I've tried

x1(all(all(cellfun((@isempty,x1),2),:,:) = [];

But it gave me this following error:

Error: Expression or statement is incorrect--possibly unbalanced (, {, or [.

PS: I cannot use "==" because its a cell array.

Thanks in advance

Luiz
  • 85
  • 1
  • 3
  • 12
  • 1
    Well, counting the parentheses, you have 5x `(` and only 3x `)` ... – tmpearce Apr 23 '13 at 00:20
  • making parentheses correct doesn't solve the error it seems – Autonomous Apr 23 '13 at 02:01
  • Please post what you get once you've corrected the problem with the parentheses. – Roney Michael Apr 23 '13 at 04:23
  • Thanks! Going to test and answer this – Luiz Apr 23 '13 at 12:01
  • I've tested this possibilities: `x1(all(all(cellfun((@isempty,x1),2),:,:))) = [];` `x1(all(all(cellfun((@isempty,x1),2),:),:)) = [];` `x1(all(all(cellfun((@isempty,x1),2)),:,:)) = [];` `x1(all(all(cellfun((@isempty,x1),2)),:),:) = [];` And all of those gave me the same error as before – Luiz Apr 23 '13 at 12:03

3 Answers3

2

There seem to be two problems here. One is the fact that you are using a 3D cell array, and it appears that you want to delete different numbers of rows from different planes. This would give you something that does not form a proper MxNxP structure, because M won't be the same.

That said, I can tell you how to remove the rows that are all empty in a 2D cell array. Let's say val is MxN. Then

val2 = val(~all(cellfun(@numel,val)==0,2),:);

If you want to work with the 3D data you described, you'll have to store the result for each plane separately in a cell. Something like this:

val2 = cell(1,1,size(val,3));
for i = 1:size(val,3)
    valplane = val(:,:,i);
    val2{i} = valplane(~all(cellfun(@numel,valplane)==0,2),:);
end
nhowe
  • 909
  • 6
  • 14
  • Also, since each cell in `val` contains only one number, I suggest storing the final result as a cell array of matrices rather than a cell array of cells. Therefore, I'd do `valplane = cell2mat(val(:, :, i));` – Eitan T Apr 23 '13 at 11:35
  • Thanks a lot, I'm testing it right now (@nhowe) Eitan T, thanks, but in some parts of the cell I have dates too – Luiz Apr 23 '13 at 12:00
  • @@nhowe I tested it and it gave me: x2{i} = valplane(~all(cellfun(@numel,x1)==0,2),:); Index exceeds matrix dimensions. – Luiz Apr 23 '13 at 12:08
  • Sorry, original post had a typo, which I have now fixed. You want `x2{i} = valplane(~all(cellfun(@numel,valplane)==0,2),:);` – nhowe Apr 24 '13 at 00:57
  • I'm VERY VERY VERY grateful ! It worked perfectly! You are awesome dude, smart code! – Luiz Apr 24 '13 at 12:17
0

This should work for you for a particular row, say the first row:

i=1;    %Row number
val(~all(cellfun(@isempty,val(:,:,i)')),:,i);

For example:

>> 
val = cell(4,8,2);
val(:,:,1) = {
[20]    []    []    []    []    []    []    []
[ 0]    []    []    []    []    []    []    []
[ 0]    []    []    []    []    []    []    []
[]      []    []    []    []    []    []    []
};
>> 
i=1;    %Row number
val(~all(cellfun(@isempty,val(:,:,i)')),:,i)

The result was:

ans = 

    [20]    []    []    []    []    []    []    []
    [ 0]    []    []    []    []    []    []    []
    [ 0]    []    []    []    []    []    []    []
Roney Michael
  • 3,964
  • 5
  • 30
  • 45
0

You cannot remove different rows from a 3D array, you can remove 'floors', or layers or 'walls'. (If you imagine a building by layer I intend a vertical and perpendicular plane to your point of vision while a wall is a vertical plane along your point of vision).

You should not store numeric data in this way, i.e. one number per cell. You incur in a 112 bytes overhead per cell when a scalar double is only 8 bytes.

According to the sparsity pattern I can observe from your example, you might benefit by converting it into a sparse array which still reference against the original size of the array but without storing 0 or []. However, sparse arrays are only 2D, where the additional layers (from a 3rd dimension) are stored consecutively along the 2nd dimension.

A simplified version of your example will clarify:

val(:,:,1) = {
[20]    []    []    []
[ 0]    []    []    []
[ 0]    []    []    []
[]      []    []    []};
val(:,:,2) = {
[ 34225]    [   215]    [    0]    [   0]    
[ 85200]    [   545]    [    0]    [   0]   
[ 65074]    [   190]    [ 1000]    [   0]   
[]          []          []         []     };

% Find non-zero empty elements (0s will be discarded automatically)
[r,c] = find(~cellfun('isempty',val));

% Convert to sparse (note the coordinates are only 2D)
sp    = sparse(r,c,[val{:}]);
sp =
   (1,1)             20
   (1,5)          34225
   (2,5)          85200
   (3,5)          65074
   (1,6)            215
   (2,6)            545
   (3,6)            190
   (3,7)           1000

% Convert to full to see what happened with the 3rd dimension
full(sp)
ans =
     20      0      0      0  34225   215     0     0     
      0      0      0      0  65074   190     0     0
      0      0      0      0  85200   545  1000     0

you can see that the second layer has been concatenated horizontally (along columns). You can use reshape if you need to recover the 3D.

The advantage of val vs sp is in the reduced storage:

  Name      Size             Bytes  Class     Attributes
  sp        3x8                200  double    sparse    
  val       4x4x2             3704  cell
Oleg
  • 10,406
  • 3
  • 29
  • 57
  • 1
    Wow, thanks a lot, it was a very different solution. Nevertheless, in my cell I have some dates, not only numeric data. Also, I need my ZEROS, because they are valuable information too. I dont need the FULLY EMPTY ROWS, only. But thanks a lot for your efforts – Luiz Apr 23 '13 at 15:59
  • Dates can be stored as serial numbers, and I recommend to do that with `datenum()`. Good remark about the zeros. – Oleg Apr 23 '13 at 17:42