【问题标题】:Replacing elements of a 3D matrix in MATLAB在 MATLAB 中替换 3D 矩阵的元素
【发布时间】:2012-11-11 23:10:30
【问题描述】:

我有一个由 3 个矩阵 500x500 元素组成的 3D 矩阵。现在,我想取第三个矩阵并用 0 替换它所有大于 100 的值。如果我有一个矩阵 a,我的代码就是:

a(a>100)=0

但是,就我而言,我需要采用 3D 矩阵的第三个矩阵,即 a(:,:,3)。 如果我现在尝试使用相同的代码:

a(:,:,3)(a(:,:,3)>100)=0

我收到消息“()-索引必须出现在索引表达式的最后。”

知道如何表达吗?

【问题讨论】:

    标签: arrays matlab 3d matrix replace


    【解决方案1】:

    只是添加另一种选择:

    A(cat(3, false(size(A,1),size(A,2),2), A(:,:,3)>100)) = 0;
    

    或者,您可以像这样在 3D 中分配索引变量:

    id(:,:,3) = A(:,:,3)>100;
    A(id) = 0;
    

    语法更简洁。

    现在进行一些速度测试:

    clc, clear all
    
    b = 250*rand(500,500, 3);
    
    % Me 1
    tic
    for ii = 1:1e2
        A=b;
        clear id
        id = cat(3, false(size(A,1),size(A,2),2), A(:,:,3)>100);
        A(id) = 0;
    end
    toc
    
    % Acorbe
    tic
    for ii = 1:1e2
        A=b;
        A(:,:,3) = (A(:,:,3)<100).*A(:,:,3);
    end
    toc
    
    % angainor 1
    tic
    for ii = 1:1e2
        A=b;
        clear id
        id = find(A(:,:,3)>100) + 2*size(A, 1)*size(A, 2);
        A(id)=0;
    end
    toc
    
    % Me 2
    tic
    for ii = 1:1e2
        A=b;
        clear id
        id(:,:,3) = A(:,:,3)>100;
        A(id) = 0;
    end
    toc
    
    % angainor 2
    tic
    for ii = 1:1e2
        A=b;
        clear id
        AA = reshape(A, [], 3);
        AA(AA(:,3)>100,3) = 0;
        A = reshape(AA, size(A,1), size(A,2), 3);
    end
    toc
    

    结果:

    Elapsed time is 1.612787 seconds. % me #1
    Elapsed time is 1.223496 seconds. % Acorbe
    Elapsed time is 1.606858 seconds. % angainor #1
    Elapsed time is 1.510153 seconds. % me #2
    Elapsed time is 0.964423 seconds. % angainor #2
    

    看来胜者已成 :)

    【讨论】:

    • 那些速度竞赛... :) 我已经包含了另一种方法。你会这么好心添加它吗? :) 虽然我没有希望。
    • @angainor:“我没有希望”......是的,当然:p
    • 不能投票两次,抱歉...现在的重点是尽量避免重塑,即处理本地副本..如果可能的话..
    • @Acorbe 好吧,重塑只是添加代码,没有实际操作。它不执行任何内存分配等。它只是您查看矩阵的方式发生了变化。所以还不错。
    【解决方案2】:

    您可以为此使用线性索引:

    id = find(A(:,:,3)>100)+2*size(A, 1)*size(A, 2);
    A(id)=0
    

    或者,您可以将 reshape 数组 A 转换为 2D 和:

    AA = reshape(A, 500*500, 3);
    AA(AA(:,3)>100,3) = 0;
    A = reshape(AA, 500, 500,3);
    

    它使用 Acorbe 的原始代码,但适用于 2D 矩阵而不是 3D :)

    【讨论】:

    • +1 不错!..我会试着弄清楚它是否可行,而无需在 3D 中重塑。
    【解决方案3】:

    怎么样

     a(:,:,3) = (a(:,:,3)<100).*a(:,:,3);
    

    ?

    【讨论】:

    • @maupertius,对不起,我也看到了它的工作原理。这个更正的版本经过更仔细的检查。我很抱歉。
    • @Acorbe 看起来你的代码是要走的路。但是,我仍然收到一条错误消息,提示“整数只能与同一类的整数或标量双精度数组合。”。如果我创建一个随机矩阵,则不会发生这种情况,但只有在我的代码中使用特定矩阵(恰好是一个只有整数值的矩阵)。
    • @maupertius 那么你需要一个演员表,因为我猜比较会加倍。应该是a(:,:,3) = int16((a(:,:,3)&lt;100)).*a(:,:,3);。将 int16 替换为您正在使用的 ints 类(int32,int64,.., 测试 btw ;))..
    • +1 现在可以了 :) 我还找到了一种方法来使您的原始想法发挥作用:)
    • @Acorbe 效果很好!感谢您的帮助
    猜你喜欢
    • 1970-01-01
    • 2017-02-27
    • 2013-03-14
    • 2013-09-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多