我在循环中有一个矩阵
m=
-132.5901 -137.2695 -114.1264 -131.4986 -134.5733 Inf
Inf Inf Inf -135.2631 -121.7322 -119.7471
-132.7978 -123.8068 -135.9385 Inf -134.1602 -117.6997
-130.1930 -134.0093 -137.4125 -128.7641 Inf -116.0473
我想要一个可以在循环中使用的命令来得到答案:
-132.5901 -137.2695 -114.1264 -131.4986 -134.5733 -119.7471
-132.7978 -123.8068 -135.9385 -135.2631 -121.7322 -117.6997
-130.1930 -134.0093 -137.4125 -128.7641 -134.1602 -116.0473
我不想使用isfinite命令的单个向量。应使用Matlab自动保留矩阵大小。
答案 0 :(得分:5)
我将假设在保留原始矩阵的大小时,您希望我们使用NaN
填充解决方案矩阵的底部。我还假设在任何给定列中可能有多个Inf
。在这种情况下,以下基于循环的解决方案适用于我:
%# Set up an example matrix
M = [Inf 2 Inf 4; 5 Inf 6 7; Inf Inf 8 Inf];
[T, N] = size(M);
%# Get an index of finite elements
I1 = isfinite(M);
%# Solution 1
Soln1 = NaN(T, N);
for n = 1:N
CurCol = M(:, n);
Soln1(1:sum(I1(:, n)), n) = CurCol(I1(:, n));
end
对于一般情况,可能存在针对此问题的完全向量化解决方案(肯定有 - 请参阅下面的更新)。但是,如果它比基于循环的解决方案提高了很多速度,我会感到惊讶。在Matlab中单循环现在非常快如果你设置问题所以你可以操作矩阵的列(而不是行),因为这些元素在内存中按顺序分配。
现在,我们假设每列只有一个Inf
。在这种情况下,问题更容易解决,可以通过以下单行完成:
%# Solution 2
Soln2 = [reshape(M(isfinite(M)), T-1, N); NaN(1, N)];
对于我设置的示例矩阵,解决方案2显然会失败,因为6个元素不能通过N(即2乘4)矩阵重新排列成T-1。
更新:好的,所以没有充分的理由,如果没有循环,我就无法做到这一点很烦人。因此,这是一个无环解决方案:
%# Solution 3
Soln3 = NaN(T, N);
I2 = bsxfun(@plus, cumsum(isfinite(M)), (0:T:T*(N-1)));
I2 = I2(:);
I2(I1 == 0) = [];
Soln3(I2) = M(isfinite(M));
对循环与非循环解决方案进行快速(非常)非严格的速度测试:
Elapsed time is 0.203997 seconds.
Elapsed time is 0.251969 seconds.
如果M
更大,非循环解决方案可能会改善(相对而言)。
现在我需要重新开始工作: - )
答案 1 :(得分:2)
以科林的回答为基础:
>> M = [Inf 2 Inf 6; 5 Inf 8 4; Inf Inf 7 Inf];
>> [N,I] = sort(M)
N =
5 2 7 4
Inf Inf 8 6
Inf Inf Inf Inf
I =
2 1 3 2
1 2 2 1
3 3 1 3
因此N
已经是可能的最终产品。
N
中的数据已排序,因此如果您不想这样做,则必须取消排序:
>> for ii = 1:size(M,2)
>> N(~isinf(N(:,ii)),ii) = M(~isinf(M(:,ii)),ii);
>> end
N =
5 2 8 6
Inf Inf 7 4
Inf Inf Inf Inf
而且,如果你真的必须摆脱inf
,只需发出一个
N(isinf(N)) = NaN;
沿线的某处(和/或在需要时将isinf
替换为isnan
)。