【问题标题】:Deleting empty rows in a 3D cell array in Matlab在 Matlab 中删除 3D 单元格数组中的空行
【发布时间】:2013-04-23 00:17:54
【问题描述】:

我有一个大的 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:我不能使用"==",因为它是一个元胞数组。

提前致谢

【问题讨论】:

  • 好吧,算上括号,你有 5x ( 而只有 3x ) ...
  • 使括号正确并不能解决看起来的错误
  • 请在纠正括号问题后发布您得到的内容。
  • 谢谢!准备测试并回答这个问题
  • 我已经测试了这种可能性: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)),:),:) = [];所有这些都给了我和以前一样的错误

标签: matlab 3d cell-array


【解决方案1】:

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

也就是说,我可以告诉您如何删除二维元胞数组中所有为空的行。假设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

【讨论】:

  • 另外,由于val 中的每个单元格只包含一个数字,我建议将最终结果存储为矩阵单元格数组而不是单元格单元格数组。因此,我会做valplane = cell2mat(val(:, :, i));
  • 非常感谢,我现在正在测试它 (@nhowe) Eitan T,谢谢,但在单元格的某些部分我也有日期
  • @@nhowe 我测试了它,它给了我:x2{i} = valplane(~all(cellfun(@numel,x1)==0,2),:);索引超出矩阵维度。
  • 对不起,原来的帖子有错字,我现在已经更正了。你想要x2{i} = valplane(~all(cellfun(@numel,valplane)==0,2),:);
  • 我非常非常非常感谢!它工作得很好!你太棒了,聪明的代码!
【解决方案2】:

这应该适用于特定行,比如第一行:

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

【讨论】:

  • 谢谢,但我想不为每个维度做这个!
【解决方案3】:

不能从 3D 阵列中移除不同的行,您可以移除“地板”、层或“墙”。 (如果你想象一个逐层的建筑物,我打算垂直且垂直于你的视野,而墙壁是沿着你的视野的垂直平面)。

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

根据我从您的示例中观察到的稀疏模式,您可能会受益于将其转换为 sparse 数组,该数组仍然引用数组的原始大小但不存储 0 或 @ 987654322@。然而,稀疏数组只是二维的,其中附加层(来自第三维)沿第二维连续存储。

您的示例的简化版本将阐明:

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,可以使用 reshape。

valsp 的优势在于减少了存储空间:

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

【讨论】:

  • 哇,非常感谢,这是一个非常不同的解决方案。然而,在我的单元格中,我有一些日期,而不仅仅是数字数据。另外,我需要我的零,因为它们也是有价值的信息。我只需要完全空的行。但是非常感谢您的努力
  • 日期可以存储为序列号,我建议使用datenum()。关于零的好评论。
猜你喜欢
  • 1970-01-01
  • 2012-03-30
  • 1970-01-01
  • 2012-02-13
  • 1970-01-01
  • 1970-01-01
  • 2019-05-24
  • 2015-11-11
  • 2011-01-26
相关资源
最近更新 更多