【问题标题】:Expand cell array iteratively迭代展开元胞数组
【发布时间】:2016-09-09 18:57:44
【问题描述】:

我有两个不同大小的单元格数组,我想将cellarray1 第一列中的单元格与cellarray2 第一列中的单元格进行比较。如果两个单元格相等,则将cellarray2 [可以是字符串,整数] 中该行的后续列中的信息放入cellarray1。我真正需要的是知道如何灵活地扩展cellarray1

两个数组的第一列是字符串,Po001, Po002 等... Cellarray1 将有每个字符串的两个副本,Po001, Po001, Po002, Po002 等。
只是,我需要匹配两个数组,如果匹配,我在cellarray2的其他列中添加信息,应该是通用的, 也就是说,第二列包含具有两个值的字符串,例如Object1, Object2。第三列包含12。只是我不知道如何用新的单元格来扩展单元格数组的行,在整个 for 循环之后会在单元格数组 1 中产生 N 新列。

for ii = 1:length(cellarray2(:,1))
     for jj = 1:length(cellarray1(:,1))
         if strcmp(cellarray2{ii,1}, cellarray1{jj,1})
            % This seems to give the results I want but I 
            % dont know how to update the original cellarray1 
            % with this new row 
            [cellarray1(ii,1:end), cellarray2(jj,1:end)]
         end
     end
end

如果能做到这一点,那就太好了。理想情况下,我想输入来自cellarray2 的信息,就在cellarray1 的第一列之后。比如,在cellarray1 中为cellarray2 的每一列创建一列,然后在cellarray1 中输入该信息,当然如果比较是true

最好的问候,
花岗岩

【问题讨论】:

  • cellarray2 中的所有内容都确定在 cellarray1 中吗?
  • 您能否举例说明 cellarray1 和 cellarray2 的(部分)是什么样的?并且,如果可能的话,还有一个输出的示例。
  • 感谢您的参与。我已经添加了您要求的信息。至于输出,它只是一个cellarray,是cellarray1和cellarray2的合并,cellarray2的行与cellarray1的正确行合并。

标签: arrays matlab cell


【解决方案1】:

您可以使用cellfunfindstrcmp 创建一个索引向量来指示cellarray1(:,1) 中的哪些行与cellarray2(:,1) 匹配

% Find the first location of match from cellarray1 in cellarray2
locIdx = cellfun(@(x)find(strcmp(x,cellarray2(:,1)),1),cellarray1(:,1)); 

现在您可以将列从cellarray2 复制到cellarray1,例如:

cellarray1(:,2:end) = cellarray2(locIdx,2:end);  
% I used 2:end assuming you want to copy only the non key columns

或者,如果您想将列附加到cellarray1

width2 = size(cellarray2,2);
cellarray1(:,end+1:end+width2-1) = cellarray2(locIdx,2:end);

【讨论】:

  • 优秀。使用 cellarray1(:,2:end) = cellarray2(locIdx,2:end) 导致尺寸不匹配。但是你写的最后一篇文章完成了这项工作(我似乎无法投票)!
【解决方案2】:

@Some Guy 的答案用 cellarray2 中的值覆盖了 cellarray1 中的值。我觉得您正在寻找一种解决方案,您可以将它们添加到数组的末尾,所以如果我在这里,将是一个解决方案:

%please always add data examples to your posts
cellarray1={'A' 1;'B' 2;'C' 3;'D' 4;'E' 5};
cellarray2={'A' 'X'; 'D' 'Y';'E' 'Z'};

%there is no width() so you have to do it like this or with size()
width1=length(cellarray1(1,:));
width2=length(cellarray2(1,:));

for ii = 1:length(cellarray2(:,1))
     for jj = 1:length(cellarray1(:,1))
         %you got the ii and jj mixed up here
         if strcmp(cellarray2{ii,1}, cellarray1{jj,1})
           %either you overwrite everything with this 
           %cellarray1(ii,1:width1+width2-1) = [cellarray1(ii,:) cellarray2(jj,2:end)];
           %or you just add them at the end on cellarray1 with this
           cellarray1(jj,width1+1:width1+width2-1) = cellarray2(ii,2:end);
         end
     end
end

请注意,当 if 情况第一次为真时,cellarray1 会将其大小从 (X,width1) 更改为 (X,width1+width2-1)。 我也觉得这里的性能不是问题,但是如果这个 cellarray1 和 cellarray2 真的很大或者这个函数应该被调用很多,你应该向量化两个 for 循环。

【讨论】:

  • 我在一开始就误解了这个问题,并相应地更新了我的答案,如果附加与覆盖是一个问题,我也添加了这一点。如果您认为我的方法是完成这项工作的好方法,请点赞。
  • 不错!在这种情况下,您应该采用他的解决方案,因为那将是我在最后提到的矢量化
  • @Granit 你应该知道cellfun 不是矢量化,它只是一个花哨的循环(但可能比简单的for 慢)。尝试对解决方案进行基准测试(使用timeit),看看什么是真正更快的。
  • 我还没有真正研究过矢量化。我自然会想到 for 循环。但肯定会看的。并感谢@EBH 了解更多信息。
  • @SomeGuy 解决方案的时间是 0.0161,而 Finn 给出的 for 循环解决方案是 0.0487。它不是一个庞大的数据集。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-07-17
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多