在Matlab中删除3D单元格数组中的空行

时间:2013-04-23 00:17:54

标签: matlab 3d cell-array

我有一个很大的 3D CELL ARRAY(x1),我必须删除空行。 我怎么能这样做?

我的单元格数组的示例(变量的某些部分):

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]
[]          []          []         []        []         []         []         []    
[]          []          []         []        []         []         []         []  
[]          []          []         []        []         []         []         []   

在这种情况下,我想排除(:,:,1)的第4行,(:,:,42)中的最后三行以及这些变量中的所有其他行。

我试过

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

但它给了我以下错误:

错误:表达式或语句不正确 - 可能 不平衡的(,{,或[。

PS:我不能使用"==",因为它是一个单元格数组。

提前致谢

3 个答案:

答案 0 :(得分:2)

这里似乎有两个问题。一个是您正在使用3D单元阵列,并且您希望从不同的平面中删除不同数量的行。这会给你一些不能形成正确的MxNxP结构的东西,因为M不会是相同的。

那就是说,我可以告诉你如何删除2D单元格数组中全部为空的行。假设val是MxN。然后

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

如果您想使用您描述的3D数据,则必须将每个平面的结果分别存储在单元格中。像这样:

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

答案 1 :(得分:0)

对于特定的行,这应该适用于您,例如第一行:

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

例如:

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

结果是:

ans = 

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

答案 2 :(得分:0)

无法从3D阵列中删除不同的行,您可以删除“地板”或图层或“墙”。 (如果你想象一层建筑物,我想要一个垂直和垂直的平面到你的视角,而一面墙是你视线的垂直平面)。

不应该以这种方式存储数字数据,即每个单元格一个数字。 当标量double只有8个字节时,每个单元产生112字节开销

根据我可以从您的示例中观察到的稀疏模式,您可能会将其转换为稀疏数组,该数组仍会引用数组的原始大小但不存储0[]。但是,稀疏数组仅为2D,其中附加层(来自第三维)沿第二维连续存储。

您示例的简化版将澄清:

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

你可以看到第二层已经水平连接(沿着列)。如果需要恢复3D,可以使用重塑。

val vs sp的优势在于减少了存储空间:

  Name      Size             Bytes  Class     Attributes
  sp        3x8                200  double    sparse    
  val       4x4x2             3704  cell