用空格填充元胞数组并重新排列

Pad cell array with whitespace and rearrange

我有一个二维元胞数组 (A = 2x3),其中包含长度不等的数值向量,形式如下:

1x3 1x4 1x2
1x7 1x8 1x3

*Size of A (in both dimensions) can be variable

我想用空格填充每个向量 {' '} 以使它们的长度等于 lens = max(max(cellfun('length',A)));- 在这种情况下,所有向量的大小都将变为 1x8 - 然后随后将元胞数组重新排列为这种形式,以便可以使用 cell2table(使用示例数据)将其转换为柱状 table:

4   1   2   1   3   4
8   5   8   4   7   9
10  12  11  5   []  11
[]  13  21  7   []  []
[]  15  []  11  []  []
[]  18  []  23  []  []
[]  21  []  29  []  []
[]  []  []  32  []  []

[ ] = 空格

即列的顺序为 A{1,1}、A{2,1}、A{1,2}、A{2,2}、A{1,3} 和 A{2,3}。

如果A = 4x3,重新排列后的前五列为A{1,1}、A{2,1}、A{3,1}、A{4,1}和A{1 ,2}.

用白色填充向量 space:

YourString = 'text here';
YourString = [YourString ' '];

如果只需要 1 个白色space。如果需要更多,您可以循环此代码以获得所需的 space 数量。

table本身已经具备打印单元格的功能

感谢@StewieGriffin:

[YourString, repmat(' ',1,197-numel(YourString)]

不幸的是,我没有时间对此进行测试,但我相信如果您想快速简单地执行此操作而无需编写显式循环,我相信这应该可行。

b = cellfun(@(c) [c, repmat(' ', 1, 197-numel(c))], a,'UniformOutput',0)

编辑:

我这边没有MATLAB,之前也没用过table,所以不知道具体是怎么用的。但是,我认为最简单的方法是使用上面的行,而不是尝试用空格填充,而是用 NaN 填充它。之后,当您使用 NaN 生成 table 时,您可以执行以下操作:

所以:

B = A(:);   % Straighten it out
C = cellfun(@(c) [c, repmat(NaN, 1, 8-numel(c))], B,'UniformOutput',0) % 1x8 vectors

%% Create table %%

tab(tab == NaN) = ' ';

抱歉,如果这没有帮助。这就是我目前所能做的。

我的 Matlab (R2013a) 版本没有 cell2table 所以像 Stewie Griffin 我不确定你需要哪种格式来进行转换。

我也不确定用 whitespace 填充 double 的向量是否是个好主意。 stringsdouble不方便混用。特别是如果在您的情况下您只想要同类类型的单元格数组列(而不是每个元素都是 cell 的列)。这意味着您必须:

  • 首先将您的数字转换为字符串(例如 char 数组)。
  • 由于列将是一个char数组,它们需要在维度上是同质的,所以你必须找到最长的字符串并使它们的长度相同。
  • 最后,您可以用必要数量的 whitespace
  • 填充 char 数组列

一种方法需要多次 cellfun 调用来探测我们需要的所有这些信息,然后才能真正执行 padding/reshaping:

%// get the length of the longest vector
Lmax = max(max(cell2mat(cellfun( @numel , A  , 'uni',0)))) ;
%// get the maximum order of magnitude
n = max(max(cell2mat(cellfun( @(x) max(ceil(log10(x))) , A  , 'uni',0)))) 
%// prepare string format based on "n"
fmt = sprintf('%%0%dd',n) ;
%// pad columns with necessary number of whitespace
b = cellfun( @(c) [num2str(c(:),fmt) ; repmat(' ', Lmax-numel(c),n)], A ,'uni',0 ) ;
%// reshape to get final desired result
b = b(:).' 

b = 
    [8x2 char]    [8x2 char]    [8x2 char]    [8x2 char]    [8x2 char]    [8x2 char]

请注意,对 str2num 的调用会产生原始元胞数组(几乎,少了 reshape 操作),因为 str2num 将忽略(return empty) 空白 个条目。

>> bf = cellfun( @str2num , b,'un',0 )
bf = 
    [3x1 double]    [7x1 double]    [4x1 double]    [8x1 double]    [2x1 double]    [3x1 double]

如果我要处理数字,我肯定更喜欢用 numeric 类型填充(也使操作稍微容易一些)。这是一个用'NaN's填充的例子:

%// get the length of the longest vector
Lmax = max(max(cell2mat(cellfun( @numel , A  , 'un',0)))) ;
%// pad columns with necessary number of NaN
b = cellfun( @(c) [c(:) ; NaN(Lmax-numel(c),1)], A ,'un',0 ) ;
%// reshape to get final desired result
b = b(:).' 

b = 
    [8x1 double]    [8x1 double]    [8x1 double]    [8x1 double]    [8x1 double]    [8x1 double]

如果您不喜欢使用 NaNs 操作,您可以选择一个不在数据集可能值中的数值。例如,如果您的所有值都应该是正整数,-1 特殊值 的一个很好的指标。

%// choose your NULL value indicator
nullNumber = -1 ;
b = cellfun( @(c) [c.' ; zeros(Lmax-numel(c),1)+nullNumber], A ,'un',0 ) ;
b = b(:).' 

cell2mat(b)
ans =
     4     1     2     1     3     4
     8     5     8     4     7     9
    10    12    11     5    -1    11
    -1    13    21     7    -1    -1
    -1    15    -1    11    -1    -1
    -1    18    -1    23    -1    -1
    -1    21    -1    29    -1    -1
    -1    -1    -1    32    -1    -1

注:

如果 -1 是您的集合的一个可能值,而您仍然不想使用 NaN,一个在我的行业中广泛使用的值(完全对 NaN) 过敏作为所有实数的 null 指标是 -999.25。除非你有一个非常具体的应用程序,否则在正常操作期间获得 恰好 [=7​​3=] 这个值的概率是如此无穷小,以至于大多数软件算法在它们时识别 null 值是可以的遇到-999.25。 (有时他们只使用 -999 如果他们只处理整数。)

还要注意在 cellfun 调用中使用 c(:)。这确保向量(在每个单元格中)将被排列为 (不管它的原始形状如何(因为你的初始向量实际上在 line 正如你在你的例子中所拥有的那样)。