【问题标题】:Replace matrix values between two values替换两个值之间的矩阵值
【发布时间】:2017-11-21 07:03:17
【问题描述】:

我尝试替换在两个值之间可接受的公差范围/距离(非零)内的两个值之间的每行值。例如:

A=[0 0 0 0 1 *0 *0 *0 *0 *0 -1 *0 *0 *0 *0 *0 *0 *0 *0 *0 *0 *0 *0 *0 *0 *0 -1 *0 *0 *0 1 0 0 0;
0 0 1 *0 *0 *0 *0 *0 *0 *0 -1 *0 *0 *0 *0 *0 *0 *0 *0 *0 *0 *0 *0 *0 *0 *0 -1 *0 *0 *0 1 0 0 0]

* 表示被视为外壳的可能值。容差为 6(例如),里面的值将被替换为第一个边界值:

A_replaced=[0 0 0 0 1 *1 *1 *1 *1 *1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -1 *-1 *-1 *-1 -1 0 0 0;
0 0 1 0 0 0 0 0 0 0 -1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -1 *-1 *-1 *-1 -1 0 0 0]

如您所见,由于两个边界之间的距离不超过 6(小于容差),因此可以将所有可以视为封闭的内容都替换为第一个边界值(包括末端闭合值)。是否有矢量化方法可以针对大尺寸矩阵执行此操作?提前致谢!

【问题讨论】:

  • 对此的预期输出是什么:[1 0 0 0 0 -1 0 0 0 -1]
  • 抱歉忘记提了。输出将是[1 1 1 1 1 1 0 0 0 -1]。第二部分被忽略,如果矩阵扩展为[1 0 0 0 0 -1 0 0 0 -1 0 0 0 0 1],则最后一个-1将被视为另一个外壳的初始边界
  • 非零值只能是 1 或 -1 还是也可以是其他值?例如。 [0 0 3 0 -1 0 -1.7 0] 可以作为输入吗?
  • 可以是任何非零值,不一定是1或-1

标签: matlab matrix


【解决方案1】:

因为I've already answered half of this question,我分两步做。请注意,您在此处提出的问题并非完全一般情况,因为您需要在此处仅放置 1 的位置处理具有一些连续非零的矩阵。这取决于您之前的问题和 cmets。

所以第一步是找到所有长度在公差范围内的零序列,并将它们替换为1。第二步是您之前的问题 - 将所有非零替换为序列的起始值。

第一步是在A 的开头添加零,因为使用linear indexing 完成所有操作并将A 视为一个长向量会很舒服,但我们不想这样做捕获跨列的零序列。我们可以去掉最后的零。

A=[
0 0 0 0 0 0.5 0.9 -1 0.1 0.3 1 1 0 0 0 0.9 -1 0.1 0 0 0 0 0.3 -1 -1 0 0 0 0 0;
0 0 0 0 0  0.1 0.3 1 -1 -1 -1 -1 0 0 0 0 0 -1 -1 -1 0 0 1 1 1 0 0 0 0 0 ];

tol=6;
A=[zeros(size(A,1),tol), A];    % add zeros at beginning of each row
A=A.';                           % working on transposed A let us index continuously the sequences


zero_starts=strfind([A(1)==0; A(:)~=0].',[1 0]).';  % indices where `0` sequences starts
zero_starts(end)=[];                                % last sequance is not enclosed   
zero_length=diff([0; find(diff(find(~A))>1)]);      % length of each of these zero-sequences
zero_tol=find(zero_length<=tol);                    % zero-sequences that shorter than tolerance
zero_tol(strfind(diff([0; zero_tol].')-1>0,[1 0])+1)=[]; % remove each second of continuous zero-seqeunces

% replace all short zero-seqeunces with `1`
sl=arrayfun(@(x)0:x-1, zero_length(zero_tol),'uni',0);
A(repelem(zero_starts(zero_tol),zero_length(zero_tol))+cat(2,sl{:}).')=1;

现在,第二步是用每个序列的第一个元素替换每个非零序列:

B=find(A);
A(A~=0)=repelem(A(B([0 ;find(diff(B)>1)]+1)),diff([0;find(diff(B)>1) ;length(B)]));

最后,我们可以将A 反转回它的形状和大小-

A=A(tol+1:end,:).'

A=[
0 0 0 0 0 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0.5 0 0 0 0 0.3 -1 -1 0 0 0 0 0;
0 0 0 0 0 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0 0 1 1 1 0 0 0 0 0 ];

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-08-31
    • 1970-01-01
    • 2018-05-02
    • 1970-01-01
    • 2020-08-08
    • 1970-01-01
    相关资源
    最近更新 更多