【问题标题】:Check whether data is present in another matrix and if so, replace it检查数据是否存在于另一个矩阵中,如果存在,则替换它
【发布时间】:2014-07-02 06:35:01
【问题描述】:

在 Octave 中,有这样的矩阵:

abc = [1 2 3; 5 7 8];
def = [5 7 9; 10 11 12];

我想要一个函数,对于 abc 中的所有 [x y z1]s,检查 def 中是否存在 [x y z2],如果存在,则替换它。

所以,我想要类似的东西

checkandreplace(abc, def);

将 abc 更改为 [1 2 3; 5 7 9]

编辑:

我能想到的最好的方法是循环方案:

for i = 1:size(abc, 1)
   index = find(ismember(def(:, [1 2]), abc(i, [1 2]), 'rows'))
   if(index)
      abc(i, :) = def(index, :)
   endif
endfor

可以做得更好吗?

编辑:

忘了补充它应该是稳定的,即它不应该改变 abc 中的行顺序。

感谢您的帮助!

【问题讨论】:

  • 你的循环有什么问题?
  • 没有错!我只是想知道是否可以使用矢量化。

标签: matlab matrix octave vectorization


【解决方案1】:

您只需拨打ismember 即可完成所有操作:

[m,I] = ismember(abc(:,1:2), def(:,1:2), 'rows');
abc(m,:) = def(I(m),:);

【讨论】:

    【解决方案2】:

    这是我的“矢量化”解决方案,没有 for 循环或 if 条件,它应该保持原始顺序:

    [x y]=find(squeeze(sum(bsxfun(@eq,permute(abc(:,[1 2]), [3 2 1]),def(:,[1 2])),2)==2));
    abc(y,:)=def(x,:);
    

    测试:

    abc =
         1     2     3
         5     7     9
    

    更快吗?大家可以测试看看...

    【讨论】:

      【解决方案3】:

      它不漂亮,但它有效 =)

      abc = [1 2 3; 5 7 8];
      def = [5 7 9; 10 11 12];
      
      abc(find(ismember(abc(:,1:2),def(:,1:2),'rows')),:) = ...
      def(find(ismember(def(:,1:2),abc(:,1:2),'rows')),:) 
      abc = 
          1    2    3
          5    7    9
      

      编辑:

      如果 abc 已排序,您可以在之后对其进行排序,使用 sortrows

      【讨论】:

      • 请检查最后的编辑,你的代码改变了这种情况的顺序:abc = [1 2 3; 5 7 8; 13 16 19; 23 27 45] 定义 = [5 7 12; 1 2 9] abc(find(ismember(abc(:,1:2),def(:,1:2),'rows')),:) = ... def(find(ismember(def(:, 1:2),abc(:,1:2),'rows')),:) abc = 5 7 12 1 2 9 13 16 19 23 27 45
      • @user34812 如果 abc 已排序,为什么不再次排序。 sortrows(abc,[1 2]) 将首先为第一列排序 abc,然后为第二列。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-07-03
      • 1970-01-01
      • 2011-05-16
      • 1970-01-01
      • 2017-08-07
      • 1970-01-01
      • 2016-07-16
      相关资源
      最近更新 更多