在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循环,因为我正在尝试加速这段代码。
答案 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
命令生成稀疏矩阵。在这种情况下,您需要将逻辑索引分解为单独的行和列索引。