我在MATLAB中有3 x n
(n
是随机数)矩阵。 n=13
的示例:
M = [40, 0, 0, 0, 41, 0, 0, 0, 0, 0, 41.6, 0, 20;
20, 0, 0, 0, 23, 0, 0, 0, 0, 0, 23, 0, 189;
102, 0, 0, 0, 192, 0, 0, 0, 0, 0, 96, 0, 21];
每行中两个非零数字之间的零个数是随机的,但这个数字在行之间总是相同的。我想像这样插入每一行:
Minter = [40, 40.25, 40.5, 40.75, 41, 41.1, 41.2, 41.3, 41.4, 41.5, 41.6, 30.8, 20;
20, 20.75, 21.5, 22.25, 23, 23, 23, 23, 23, 23, 23, 106, 189;
102, 124.5, 147, 169.5, 192, 176, 160, 144, 128, 112, 96, 58.5, 21];
所以我想用用线性插值方法得到的数字替换零。
我写了自己的功能来做到这一点。我正在使用MATLAB函数find
来搜索>0
的数字索引,然后根据两个索引之间的差异(来自find
函数)并依赖于第一个左右非零数字(来自原始矩阵),我计算这两个非零数字之间的数字,并用原始矩阵中的这些数字替换零。我正在分别处理每一行。
这种方法工作正常,但速度不是很快。在MATLAB中有更快的方法吗?我尝试了interp1
功能,但没有取得多大成功。
答案 0 :(得分:3)
是的,你仍然可以使用interp1
,但你必须聪明一点。注意到你分别插入矩阵的每一行这一事实,我们可以使用find
,我们可以对矩阵的转置进行操作,以找到那些列主要位置不为零。这很重要,因为我们想要插入每行的矩阵值,find
按列主要顺序工作。如果要每行操作,则需要转置矩阵以获得所需的效果。
完成后,您可以使用这些索引以及矩阵转置中非空的关键点中的那些值,然后使用从1到尽可能多的元素的查找点。在M
中填写M
中为零的值。这只会给我们一个1D数组,所以我们需要reshape
矩阵并在完成后转置回来。转置也很重要,因为reshape
以列为主的方式重塑了一个向量,所以最后一步确保我们得到行主要的所有内容。
做这样的事情:
%// Your matrix
M=[40, 0, 0, 0, 41, 0, 0, 0, 0, 0, 41.6, 0, 20;
20, 0, 0, 0, 23, 0, 0, 0, 0, 0, 23, 0, 189;
102, 0, 0, 0, 192, 0, 0, 0, 0, 0, 96, 0, 21];
%// New code
Mt = M.'; %// Transpose
ind = find(Mt); %// Find column-major indices
Minter = interp1(ind, Mt(ind), 1:numel(M)); %// Interpolate per row
Minter = reshape(Minter, size(M,2), size(M,1)).'; %// Reshape and transpose back
我们得到:
Minter =
Columns 1 through 8
40.0000 40.2500 40.5000 40.7500 41.0000 41.1000 41.2000 41.3000
20.0000 20.7500 21.5000 22.2500 23.0000 23.0000 23.0000 23.0000
102.0000 124.5000 147.0000 169.5000 192.0000 176.0000 160.0000 144.0000
Columns 9 through 13
41.4000 41.5000 41.6000 30.8000 20.0000
23.0000 23.0000 23.0000 106.0000 189.0000
128.0000 112.0000 96.0000 58.5000 21.0000
这与您想要的输出一致。