【问题标题】:Creating new matrix from combining two other by using an if-statement in MATLAB通过在 MATLAB 中使用 if 语句从组合两个其他矩阵创建新矩阵
【发布时间】:2017-03-23 18:05:53
【问题描述】:

我有一个尺寸为 8x6 的矩阵。这个矩阵中有一半的元素是 0,这完全没问题。现在,我想参考另一个 160x6 的矩阵。 8x6 矩阵基于 160x6 矩阵,并来自滚动窗口(20 个观察值)。

我想创建一个新矩阵(同样是 160x6)。每当我的 8x6 矩阵中的一个元素等于 0 时,我希望原始 160x6 矩阵中引用该元素(为 0)的 20 个观察值也为 0。

我尝试了以下方法:

for t=1:T
    for i=1:N
    if B(:,i) == 0;
    C(t,i) = 0;
    else
    C(t,i) = A(t,i);
    end
    end
end

我在哪里:

A 是 160x6 矩阵

B 是 8x6 矩阵

C 是 160x6 矩阵的新输出

目前,我获得了一个“新”的 160x6 矩阵 (C),但它完全复制了原始的 160x6 矩阵 (A)。所以循环或者if语句是不正确的。

【问题讨论】:

  • 在这个例子中我假设T = 160N = 6
  • 是的。很抱歉漏掉了这个。
  • 您还错过了AB 矩阵。举个输入数据的例子会更容易。
  • B(:,i) == 0 永远不会成立,因为您将矩阵的整个列与零进行比较,除非您的矩阵中只有一行,因此 B(:,i) 是一个标量。这就是为什么你的 C 和 A 一样

标签: matlab loops if-statement matrix replace


【解决方案1】:

我将根据我对您的问题的理解举一个小例子。

>> B = randi(10,8,6) - 5; % Sample B matrix

B =

    -4     0    -4     4     5     1
    -2     3     3     1     3    -4
    -1     3     1    -3     1     4
     2     5     0    -2     0     4
    -3     4     5     4    -4     3
     3    -1     2    -4     2    -3
    -3     2     2     0    -4     2
     2    -3     4    -3    -4     1

在此矩阵中,您要识别具有0 的位置,例如(1,2), (4,3), (4,5)。并且在 160 x 6 矩阵中 (1:20,2), (61:80,3), (61:80,5) 应该为零。您可以使用repelem 函数来获取此类索引。

>> zeroIdx = repelem(B == 0,20,1)

zeroIdx 将在 B 为零时包含 true,每行重复 20 次。

>> C = A
>> C(zeroIdx) = 0 % Assign 0 to C using zeroIdx

【讨论】:

    【解决方案2】:

    检查以下内容:

    %Initialize A matrix with ones for testing.
    A = ones(160, 6);
    B = ones(8, 6);
    
    %Put few zeros in B
    B(1:2:end,1) = 0;
    B(5:3:end,3) = 0;
    
    T = 160;
    N = 6;
    
    for t=1:T
        for i=1:N
            %The formula k = floor((t-1)/20)+1 equals 1, 1, 1, 1... 20 times, then 2, 2, 2, 2... 20 times
            k = floor((t-1)/20)+1;
            if B(k,i) == 0;
                C(t,i) = 0;
            else
                C(t,i) = A(t,i);
            end
        end
    end
    
    %Display C as an image (for testing).
    figure;imagesc(C);colormap gray
    

    测试结果图片:


    k 的值如下图所示:

    T=160;t = 1:T;k = floor((t-1)/20)+1;figure;plot(t, k, 'x');grid on;
    


    我能实现的最紧凑的解决方案:

    C = A.*imresize((B ~= 0), size(A), 'nearest');
    

    【讨论】:

    • 嘿Rotem。哇!非常感谢。该代码正在运行,我可以将其转移到我自己的代码中。我非常感谢!您添加的公式很棒。 ;) 我还有一个问题。与我的情况无关,但仍然感兴趣。在给定的示例中,我有 8 个周期,每个周期有 20 次观察。因此,它与 160 个整体观测值完美匹配。但是如果我有 165 个观察值呢?我认为代码会省略最后 5 个,因为索引超过了矩阵维度,对吧?有没有机会克服这个问题?
    • 假设 5 个额外的观察值应该从 A 移动到 C 不变。解决方案可以是:1. 在循环之前将矩阵 A 复制到 C C = A; 2. t 迭代到不超过矩阵维度的最大值(例如最多160)。您可以按如下方式计算上限值:floor(165/20)*20.
    • 如果有5个额外的观察属于B的最后一个元素,可以在k = floor((t-1)/20)+1;之后使用之前修改代码限制k,添加代码k = min(k, size(B,1));
    • Hey Rotem,今天您的所有回答给我的巨大帮助让我感到惊讶。非常感谢你!我会将我得到的所有三个答案都标记为“有用”,但显然这对像我这样的新人不起作用;)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-07-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多