我有一些2D数组surf
像这样:(但更长,更长。在许多情况下,数万个)
surf = [10, 10, 20, 20, 30, 30
10, 10, 20, 20, 30, 30
10, 10, 20, 20, 30, 30
10, 10, 20, 20, 30, 30]
我也有一个像这样的数组“ section” :(与浏览的行数相同)
值可以是NaN。
section = [4
NaN
6
2]
该数组告诉我,我需要获取surf
中的每一列,每一行。
我最终想构造一个看起来像这样的第三个数组:
output = [20
NaN
30
10]
每个值是surf
数组中的行,即section
为同一行定义的行。
我对如何解决这个问题感到非常困惑。 我尝试过类似的事情:
myArray = surf(:, section);
但是由于明显的原因不起作用。部分是值的数组,而不是单个值。
我对MATLAB还是很陌生,只具有非常不同的语言的经验,将不胜感激。我是MATLAB似乎所做的所有矢量化/隐式循环/等工作的新手。
答案 0 :(得分:2)
这是三个尝试。请注意,由于mysurf
是一种MATLAB函数,因此我已将变量名更改为surf
,并且更改了数据以更清楚地选择了哪个变量:
mysurf = [ 1, 2, 3, 4, 5, 6
7, 8, 9, 10, 11, 12
13, 14, 15, 16, 17, 18
19, 20, 21, 22, 23, 24];
section = [4
NaN
6
2];
% first attempt by replacing NaN...
tmp = section;
tmp(isnan(tmp)) = 1;
result1 = NaN(size(section));
for c = 1 : numel(result1)
result1(c) = mysurf(c, tmp(c));
end
% and changing the result to NaN afterwards
result1(isnan(section)) = NaN;
% Second attempt by using an if
result2 = NaN(size(section));
for c = 1 : numel(result2)
if ~isnan(section(c))
result2(c) = mysurf(c, section(c));
end
end
更新另外,这是一次不使用循环的尝试(受到@obchardon的回答挑战):
mysurf = [ 1, 2, 3, 4, 5, 6
7, 8, 9, 10, 11, 12
13, 14, 15, 16, 17, 18
19, 20, 21, 22, 23, 24];
section = [4
NaN
6
2];
width = size(mysurf,2);
tmp = mysurf';
linidx = ((1:numel(section))-1) .* width + section';
result = NaN(size(section));
result(~isnan(linidx)) = tmp(linidx(~isnan(linidx)));
答案 1 :(得分:2)
在这种情况下,for循环可能更适合,但是如果您想要向量化的解决方案:
% Define matrix size
m = 5;
n = 6;
% Random matrix
A = round(rand(m,n)*10)
% Index including NaN value
idx1 = [1 NaN 3 4 5];
% Correction of the row index to get a linear index, it will also delete the NaN value
% Sub2ind could have done the same job, but sub2ind does not support NaN value
% so we save a few line here
idx2 = fillmissing(idx1,'c',1)*m-m+[1:m];
% Get the value and retrieve the NaN value
out = A(idx2).*idx1./idx1
对于
A =
4 8 9 1 8 9
2 8 0 2 7 2
4 4 2 9 7 3
9 0 8 7 0 9
0 1 9 6 7 8
出局将是:
out =
4 NaN 2 7 7
答案 2 :(得分:0)
正如@obchardon所评论的那样,典型的做法是:
result = surfs(1, section)
输出:
结果= 20 20 30 10
但是由于您说这行不通,因此可以使用for循环,如下所示:
surfs = [10, 10, 20, 20, 30, 30; 10, 10, 20, 20, 30, 30; 10, 10, 20, 20, 30, 30; 10, 10, 20, 20, 30, 30]
section = [4; 4; 6; 2]
result = zeros(length(section), 1)
for i = 1 : length(result)
result(i) = surfs(i, section(i))
end
输出:
结果= 20 20 30 10