Структура в ячейку (или матрицу) в Matlab

У меня есть структура с полями ID,Coor,Misc,Conn. ID и Misc являются двойными, однако 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, а затем изменив уровень вложенности. Я просто не совсем уверен, как это сделать.


person user1007692    schedule 21.10.2011    source источник


Ответы (2)


Сначала сделайте несколько примеров данных:

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'   

Не могу сказать по вашему вопросу, но если вы хотите, чтобы все числовые поля представляли собой массив внутри одной ячейки, это легко сделать. Удачи!

person John Colby    schedule 21.10.2011
comment
Однако элегантное решение для тех, у кого есть пустые значения для некоторых элементов, таким образом учитывает их (мне было плохо, что я не упомянул об этом раньше): Point_cell = arrayfun(@(x) [{x.ID} {x.Coordinate(1)} {x.Coordinate(2)} {x.Coordinate(3)} {x.Misc} {num2str(x.Connections)}], Node, 'UniformOutput', 0); - person user1007692; 22.10.2011

Вот немного другое решение с использованием 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]
person Amro    schedule 22.10.2011