在Matlab中结构化到单元格(或矩阵)

时间:2011-10-21 19:12:12

标签: matlab struct matrix cell

我的结构包含字段IDCoorMiscConnIDMisc是双精度数,但Coor是1x3向量,Conn是1xn向量(其中n理论上可以从0到inf)。

Point(x).ID = [x]
Point(x).Coordinate = [xPos yPos zPos]
Point(x).Misc = [randomDouble]
Point(x).Conn = [someVectorOfNumbers]

我希望将其映射到单元格数组上,而不使用FOR循环。

输出的一个例子:

'ID    xPos    yPos    zPos    Misc    Conn'
 1      0        0       0       0    '0 1 2'
 2      1        1       1       1      ''     
 ...
 x      x        x       x       x      '2'

请注意Point.Conn,其数字向量将转换为字符串。

我遇到的问题是将Point.Coordinate分解为三个元素,并将Point.Conn转换为字符串。

我觉得这可以使用struct2Cell然后更改嵌套级别来完成。我只是不确定该怎么做。

2 个答案:

答案 0 :(得分:3)

首先制作一些示例数据:

n = 10;

ID         = num2cell(randperm(n)');
Coordinate = mat2cell(randn(n, 3), ones(n,1));
Misc       = num2cell(randn(n,1));
Conn       = arrayfun(@randperm, randperm(n), 'UniformOutput', 0)';

Point = struct('ID', ID, 'Coordinate', Coordinate, 'Misc', Misc, 'Conn', Conn);

现在检查一下:

>> Point

Point = 

10x1 struct array with fields:
    ID
    Coordinate
    Misc
    Conn

>> Point(1)

ans = 

            ID: 7
    Coordinate: [-0.0571 -1.1645 2.4124]
          Misc: 0.0524
          Conn: [3 2 1]

现在使用arrayfun()来扫描结构数组Point的元素。我们定义了一个通用函数x来对Point的每个元素进行操作,格式化你所描述的行:

Point_cell = arrayfun(@(x) [num2cell([x.ID x.Coordinate x.Misc]) num2str(x.Conn)], Point, 'UniformOutput', 0);
Point_cell = vertcat(Point_cell{:})

现在检查输出:

ans = 

    [ 7]    [-0.0571]    [-1.1645]    [ 2.4124]    [ 0.0524]    '3  2  1'            
    [ 5]    [ 0.2918]    [ 0.4948]    [ 0.7402]    [-1.9539]    '1  2'               
    [ 3]    [-0.6146]    [-1.2158]    [ 0.3097]    [ 0.5654]    '3  4  1  2'         
    [10]    [-0.0136]    [ 1.5908]    [-0.5420]    [ 0.0778]              [1x25 char]
    [ 2]    [ 0.4121]    [ 0.5265]    [ 0.1223]    [ 0.0807]              [1x22 char]
    [ 1]    [-0.9371]    [ 0.2648]    [ 0.9623]    [ 0.7947]    '1  2  5  4  3'      
    [ 4]    [ 0.8352]    [-0.3936]    [-0.2540]    [ 1.0437]    '6  2  3  7  4  1  5'
    [ 8]    [ 1.0945]    [-2.1763]    [ 1.8918]    [ 0.8022]    '1'                  
    [ 6]    [ 0.3212]    [-1.1957]    [-1.2203]    [-0.4688]              [1x37 char]
    [ 9]    [ 0.0151]    [ 0.3653]    [-0.3762]    [-0.0466]    '3  5  4  2  6  1'   

无法从您的问题中得知,但如果您希望将所有数字字段作为单个单元格内的数组,那么这是一个很容易的调整。祝你好运!

答案 1 :(得分:2)

以下是使用STRUCT2CELL

的略有不同的解决方案
%# build a sample array of structures
id = num2cell((1:10)',2);    %'
coords = num2cell(rand(10,3),2);
misc = num2cell(rand(10,1),2);
conn = arrayfun(@(n)randi(5,[1 n]), randi([0 6],[10 1]), 'UniformOutput',false);
p = struct('ID',id, 'Coordinate',coords, 'Misc',misc, 'Conn',conn);

%# convert to cell array
h = fieldnames(p)';          %'
X = struct2cell(p)';         %'

%# split 'coords' field into 3 separate columns
h2 = {'xPos' 'yPos' 'zPos'};
X2 = num2cell( cell2mat(X(:,2)) );

%# convert 'conn' field to string
X4 = cellfun(@num2str, X(:,4), 'UniformOutput',false);
X4 = regexprep(X4, '[ ]+', ' ');    %# clean multiple spaces as one

%# build final cell array with headers
C = [h(1) h2 h(3:4) ; X(:,1) X2 X(:,3) X4]

结果:

>> C
C = 
    'ID'    'xPos'       'yPos'        'zPos'       'Misc'        'Conn'       
    [ 1]    [0.78556]    [ 0.46707]    [0.66281]    [ 0.46484]    '3'          
    [ 2]    [0.51338]    [  0.6482]    [0.33083]    [ 0.76396]    '2 1 2 5 1 2'
    [ 3]    [ 0.1776]    [0.025228]    [0.89849]    [  0.8182]    '1 3 1 5'    
    [ 4]    [0.39859]    [ 0.84221]    [0.11816]    [ 0.10022]    '1 1 2'      
    [ 5]    [0.13393]    [ 0.55903]    [0.98842]    [ 0.17812]    '3 1 5 2 2 1'
    [ 6]    [0.03089]    [  0.8541]    [0.53998]    [ 0.35963]    ''           
    [ 7]    [0.93914]    [ 0.34788]    [0.70692]    [0.056705]    '2 1 3 4 4'  
    [ 8]    [0.30131]    [ 0.44603]    [0.99949]    [ 0.52189]    '1 1 4 5 3'  
    [ 9]    [0.29553]    [0.054239]    [0.28785]    [ 0.33585]    '1 5 2'      
    [10]    [0.33294]    [ 0.17711]    [0.41452]    [ 0.17567]    '2'     
例如,第二个结构是:

>> p(2)
ans = 
            ID: 2
    Coordinate: [0.51338 0.6482 0.33083]
          Misc: 0.76396
          Conn: [2 1 2 5 1 2]