【问题标题】:MATLAB creating of struct-vectorMATLAB 创建结构向量
【发布时间】:2013-04-29 08:36:58
【问题描述】:

给定一些数据——例如(在我的例子中)——像下面的表格

Name  |pos_x|pos_y|pos_z
------------------------
Point1|   .1|   .1|   .2
Point2|  0.0|  0.0|   .1
Middle|   .1|   .2|   .1
Point3|  0.0|    1|  0.0

也许在从 excel 导入该数据后,所有值都存储在一个单元格数组中(我们称之为celldata)。
出于测试目的,可以使用以下行创建此单元格

celldata={'Point1' .1 .1 .2;'Point2' 0 0 .1;'Middle' .1 .2 .1;'Point3' 0 1 0}

在本例中,单元格大小为 4x4。

目前我正在使用以下几行创建一个结构

point.name=char(celldata(:,1));
point.posxyz=cell2mat(celldata(:,2:4));

这导致point size 1x1 Class struct。我正在寻找一种有效的方法将其生成为point size 4x1 Class struct - 因此上面表格中的每一行都有一个元素 - 都具有相同的内部结构:名称和坐标。
我已经尝试过cell2struct,但它只能沿一个维度展开,而无需将一些列组合在一起——据我所知。
此外,这不是 Preallocate structure of cells in matlab 的重复,因为在这种情况下,我有许多不同的列 - 甚至可能是动态列数。

【问题讨论】:

  • 您认为dataset 会有帮助吗?
  • 我认为循环遍历元素会很好:例如for punkt=point,disp([punkt.name ':' num2str(norm(punkt.posxyz))]),end。尤其是不需要检查有多少元素。你知道什么更好的吗?

标签: arrays matlab struct cell dimension


【解决方案1】:
cellData = {'Name', 'pos_x', 'pos_y'; 'Harry', 34, 2; 'Bernard', 5, 11}

然后

for col = 1:size(cellData ,2)
    fieldName = cellData{1, col};
    c = cellData (2:end, col);
    [point(1:length(c)).(fieldName)] = c{:};
end

现在

point(1)

ans = 

     Name: 'Harry'
    pos_x: 34
    pos_y: 2

point(2)

ans = 

     Name: 'Bernard'
    pos_x: 5
    pos_y: 11

编辑:

如果您只想拥有 2 个字段,即 Nameposxyz,则:

 [M, N] = size(celldata);
 names = celldata(:,1);
 [point(1:M).Name] = names{:};
 xyz = mat2cell(cell2mat(celldata(:,2:end)), ones(M,1), N - 1);
 [point(1:M).posxyz] = xyz{:};

现在celldata={'Point1' .1 .1 .2;'Point2' 0 0 .1;'Middle' .1 .2 .1;'Point3' 0 1 0}

point(1)

ans = 

          Name: 'Point1'
        posxyz: [0.1000 0.1000 0.2000]

point(2)

ans = 

      Name: 'Point2'
    posxyz: [0 0 0.1000]

【讨论】:

  • 感谢@Dan 的这个想法,但我真的不喜欢一个一个地分配名称(例如)的需要。请考虑一个有数百行或更多行的表格。进一步的想法?
  • 添加当然可以像在rmfield.m 中那样完成 - 但我认为这应该可以更快一些,或者?
  • @BastianEbeling 数百行或数百列?
  • 嗨,丹,在我的评论中,我提到了数百行。但是(就像我上次的编辑一样,你可能没有看到)也可能出现很多列。
  • @BastianEbeling Well 行显然不是问题,只需将4 替换为length(C),对于列,我认为你最好的选择是一个简单的for 循环,所以如果col是循环变量,C = celldata{:, col} 然后是[point(1:length(C), col).(C{1})] = C{2:end}
【解决方案2】:

尝试使用struct 将元胞数组作为输入:

C = cellfun(@(x,y,z)[x y z], celldata(:,2), celldata(:,3), celldata(:,4), 'Uniform', 0);
point = struct('name', celldata(:, 1), 'posxyz', C);

请注意,对于 posxyz 字段,我通过连接 celldata 的单元格创建了一个新的单元格数组。

如果您以后想添加其他字段,可以使用dealcomma-separated lists。以下示例将来自celldata 第四列的值存储在一个名为pos_z 的新字段中:

[point(:).pos_z] = deal(celldata{:, 4});

【讨论】:

  • 谢谢,这真是个好主意。在我的例子中,还有更多的列——为了便于阅读,我想在一个源代码行中添加每一列(或 xyz 中的一对列)。您知道将字段添加到您创建的点结构的方法吗?
  • @BastianEbeling 当然。您需要使用dealcomma-separated lists。查看修改后的答案。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-04-22
  • 2012-04-20
  • 1970-01-01
  • 2016-04-11
  • 1970-01-01
  • 2014-07-27
  • 2014-03-03
相关资源
最近更新 更多