Reputation: 85
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
Upvotes: 0
Views: 1524
Reputation: 929
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
Upvotes: 2
Reputation: 10676
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
Upvotes: 0
Reputation: 3994
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] [] [] [] [] [] [] []
Upvotes: 0