如何将数组设置为等于二维数组中存储在第三个数组中的列中的值?

时间:2019-07-31 17:37:57

标签: arrays matlab multidimensional-array

我有一些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似乎所做的所有矢量化/隐式循环/等工作的新手。

3 个答案:

答案 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