Структура към клетка (или матрица) в 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