矩阵返回向量的逻辑索引 - 需要初始化吗?

时间:2014-09-11 10:30:35

标签: matlab matrix indexing

在Matlab中,当为矩阵创建逻辑索引时,似乎需要初始化NaN(或其他?)矩阵来保留相对位置。例如,请考虑以下示例:

clear all; close all; clc;

Data = [1 2 3 4; 3 40 5 6; 5 6 7 8];
ind = logical([0 0 0 0;0 1 1 0;0 1 0 0]); 

tic
x1 = NaN * ones(3,4); 
y1 = NaN * ones(1,4); y2 = y1;
x1(ind) = Data(ind); % writing to pre-allocated NaN matrix (necessary?)
y1(1:4) = nanmean(x1,1); % take NaN-mean - good result
toc

% Can we get rid of x1? The following obviously does not work:
y2(1:4) = nanmean(Data(ind),1);

如上面的代码所述,Data(ind)将返回一个向量,而不是保留原始大小。到目前为止,我唯一的解决方案是使用x1,它被初始化为具有正确的大小。那么:创建一个完整的(x1)NaN矩阵是必要的吗?关于如何避免这种想法的任何想法?我没有寻找for循环,因为我正在尝试加速这段代码。

2 个答案:

答案 0 :(得分:1)

你可以使用accumarray在这里拯救自己,但是你仍然需要为输出预分配,这是好的,我希望无论如何你都要使用那个输出,否则你不需要它第一名。对于您的问题案例,您可以在此处使用两个appproaches。

方法#1

[~,c] = find(ind); %// get column indices
out = NaN(1,size(Data,2)); %// pre-allocate for output

calc_result = accumarray(c,Data(ind),[], @mean)  %// get mean calculated results
array1 = 1:max(c)
vind = ismember(array1,c) %// valid indices
out(array1(vind)) =  calc_result(vind)

方法#2

[~,c] = find(ind); %// get column indices OR try c = ceil(find(ind)/size(ind,1))
vind = c(diff([0 ; c])~=0);   %// valid indices

out(1,1:size(Data,2)) = NaN; %// pre-allocate for output
calc_result = accumarray(c,Data(ind),[], @mean); %// get mean calculated results
out(vind) =  calc_result(vind);

使用方法#1 -

与可信输出y1进行比较的完整代码
clear all; close all; clc;

% Initialization
x1 = NaN * ones(3,4); 
y1 = NaN * ones(1,4); 
y2 = y1;

Data = [
    1 2 3 4; 
    3 4 5 6; 
    5 6 7 8]

% Indices of data to be averaged over rows:
ind = logical([0 0 0 0;0 1 0 0;0 1 0 1])

x1(ind) = Data(ind); % writing to pre-allocated NaN matrix (necessary?)
y1(1:4) = nanmean(x1,1) % take NaN-mean - good result

[~,c] = find(ind); %// get column indices
out = NaN(1,size(Data,2)); %// pre-allocate for output

calc_result = accumarray(c,Data(ind),[], @mean);
array1 = 1:max(c);
vind = ismember(array1,c);
out(array1(vind)) =  calc_result(vind)

输出 -

Data =
     1     2     3     4
     3     4     5     6
     5     6     7     8
ind =
     0     0     0     0
     0     1     0     0
     0     1     0     1
y1 =
   NaN     5   NaN     8
out =
   NaN     5   NaN     8

答案 1 :(得分:0)

简短回答:是的,对于完整的矩阵,需要进行预初始化以获得正确的矩阵大小和形状。

如果您担心浪费内存,可以使用sparse命令生成稀疏矩阵。在这种情况下,您需要将逻辑索引分解为单独的行和列索引。