我有一个4x2矩阵A:
A = [2 NaN 5 8; 14 NaN 23 NaN]';
我想用每列中各自索引替换A中的非NaN值。输出结果如下:
out = [1 NaN 3 4; 1 NaN 3 NaN]';
我知道如何手动为每一列做到这一点,但是我希望有一种自动解决方案,因为我需要处理更大的矩阵。 有人有任何想法吗?
out = bsxfun(@times, A-A+1, (1:size(A,1)).');
工作原理:
A-A+1
用 1
替换 A
中的实际数字,并将 NaN
保留为 NaN
(1:size(A,1)).'
是行索引的列向量bsxfun(@times, ...)
将上述两者都通过单例扩展进行乘法运算。正如@thewaywewalk指出的那样,在Matlab R2016或更新版本中,bsxfun(@times...)
可以被.*
替换,因为默认启用了单例扩展:
out = (A-A+1) .* (1:size(A,1)).';
@Dev-Il提出的另一种选择是
out = bsxfun(@plus, A*0, (1:size(A,1)).');
这有效是因为乘以0
将实际数字替换为0
,并保持NaN
不变。
将 ind2sub
应用于使用 isnan
创建的掩模即可。
mask = find(~isnan(A));
[rows,~] = ind2sub(size(A),mask)
A(mask) = rows;
ind2sub
的第二个输出也需要请求(但使用~
忽略)[rows, ~]
,以指示您想要获得二维矩阵的输出。A =
1 1
NaN NaN
3 3
4 NaN
A.' =
1 NaN 3 4
1 NaN 3 NaN
'
和 .'
。
[n,m] = size(A);
B = ndgrid(1:n,1:m);
B(isnan(A)) = NaN;
甚至可以(在受到Luis Mendo启发后)。
[n,m] = size(A);
B = A-A + ndgrid(1:n,1:m)
B = A-A + ndgrid(1:size(A,1),1:size(A,2))
[rows,cols] = find(~isnan(A)); A(sub2ind(size(A), rows, cols)) = rows;
- Luis Mendo1
:B = A-A + ndgrid(1:n,1:m)
:-) - Luis Mendokron
*咳咳*)很有趣。A*0
与 A-A
相同。A = [2 NaN 5 8; 14 NaN 23 NaN].';
out = A*0 + kron((1:size(A,1)).', ones(1,size(A,2)))
out =
1 1
NaN NaN
3 3
4 NaN
(A-A+1) .* (1:size(A,1)).'
,是吗? - Robert SeifertA-A
根据输入可以得到零或NaN
:-) - Luis MendoNaN
? - rayryengx-x
都是零,但对于inf
或NaN
不是。因此,A-A
在原有数字的位置插入零,并保留NaN
条目。 - Luis Mendo