我有3列数据:
time = [1;2;3;4;5;6;7;8;9;10;11;12;13;14;15;16];
category = [1;1;1;1;2;2;2;2;3; 3; 3; 3; 4; 4; 4; 4];
data = [1;1;0;1;2;2;1;2;3; 3; 2; 3; 4; 4; 4; 3];
我使用以下内容来提取每个类别的最小数据值:
groupmin = accumarray(category,data,[],@min)
哪个输出:
groupmin = [0;1;2;3]
但是,我真的希望有一个输出也告诉我最小值来自哪个时间点,例如
timeofgroupmin = [3;7;11;16]
groupmin = [0;1; 2; 3]
或者,我希望在自己的向量中输出最小值,其中任何行的NaN都不是其最小值,例如。
groupminallrows = [NaN;NaN;0;NaN;NaN;NaN;1;NaN;NaN;NaN;2;NaN;NaN;NaN;NaN;3];
任何一种方法都可以解决我的问题。作为一名Matlab新手,我很难知道要搜索哪些术语。
答案 0 :(得分:3)
如果同一类别的所有数据都在一次运行中并且类别已按照示例排序,则此方法有效。每个类别中允许使用几个最小化器。
r = accumarray(category,data,[],@(v) {(min(v)==v)});
r = vertcat(r{:});
groupminallrows = NaN(size(data));
groupminallrows(r) = data(r);
答案 1 :(得分:1)
将accumarray
与自定义功能结合使用:
time = [1;2;3;4;5;6;7;8;9;10;11;12;13;14;15;16];
category = [1;1;1;1;2;2;2;2;3; 3; 3; 3; 4; 4; 4; 4];
data = [1;1;0;1;2;2;1;2;3; 3; 2; 3; 4; 4; 4; 3];
groupmin = accumarray( A(:,1), A(:,2), [], @min)
你拥有的是什么,但要获得最小值的指数和他们的时间,你需要min
函数的第二个输出,我不知道是否可以与accumarray一起使用时获得。但是有以下解决方法:
groupidx = accumarray( category, data, [], @(x) find(x == min(x) )).'
occ = cumsum(hist(category,unique(category)))
idx = -occ(1)+occ+groupidx;
timeofgroupmin = time(idx).'
groupmin = data(idx).'
groupmin =
0 1 2 3
timeofgroupmin =
3 7 11 16
您想要的NaN
- 矢量:
groupminallrows = NaN(1,numel(data));
groupminallrows(idx) = data(idx)
关于你的评论:
我假设的原因是,每组中有多个最小值,然后find
返回一个数组。要解决此问题,您可以将find(x == min(x))
替换为find(x == min(x),1)
。但是你会在每组中首先出现每个最小值。
如果不需要,我说accumarray
通常是错误的方法。
答案 2 :(得分:1)
试试这个解决方案:
% first we group the data into cell according to the group they belong to
grouped = accumarray(category, data, [], @(x){x});
% find the minimum and corresponding index of each group
[mn,idx] = cellfun(@min, grouped);
% fix index by offsetting the position to point the whole data vector
offset = cumsum([0;cellfun(@numel, grouped)]);
idx = idx + offset(1:end-1);
% result
[mn(:) idx(:)]
assert(isequal(mn, data(idx)))
% build the vector with NaNs
mnAll = nan(size(data));
mnAll(idx) = mn;
得到的载体:
>> mn'
ans =
0 1 2 3
>> idx'
ans =
3 7 11 16
>> mnAll'
ans =
NaN NaN 0 NaN NaN NaN 1 NaN NaN NaN 2 NaN NaN NaN NaN 3
这是另一种解决方案:
% find the position of min value in each category
idx = accumarray(category, data, [], @minarg);
% fix position in terms of the whole vector
offset = cumsum([0;accumarray(category,1)]);
idx = idx + offset(1:end-1);
% corresponding min values
mn = data(idx);
我正在使用以下自定义函数从min
中提取第二个输出参数:
function idx = minarg(X)
[~,idx] = min(X);
end
结果与上述相同。