gpt4 book ai didi

matlab - 来自具有最大/最小值的 accumarray 的索引

转载 作者:太空宇宙 更新时间:2023-11-03 20:35:59 25 4
gpt4 key购买 nike

我有一个向量和一个大小相同的元胞数组(带有重复字符串)。元胞数组定义组。我想在每个组的向量中找到最小/最大值。

例如:

value = randperm(5) %# just an example, non-unique in general
value =
4 1 2 3 5
group = {'a','b','a','c','b'};
[grnum, grname] = grp2idx(group);

我使用 ACCUMARRAY为此功能:

grvalue = accumarray(grnum,value,[],@max);

所以我有了具有唯一组名 (grname) 和新向量 (grvalue) 的新元胞数组。

grname = 
'a'
'b'
'c'
grvalue =
4
5
3

但我还需要从包含在新向量中的旧向量中找到值的位置索引。

gridx = 1 5 4

有什么想法吗?没有必要使用 accumarray,但我正在寻找快速矢量化解决方案。

最佳答案

我能看到的最佳矢量化答案是:

gridx = arrayfun(@(grix)find((grnum(:)==grix) & (value(:)==grvalue(grix)),1),unique(grnum));

但我不能将其称为“快速”矢量化解决方案。 arrayfun 确实很有用,但通常不比循环快。


但是,最快的答案并不总是矢量化的。如果我按照您编写的代码重新实现代码,但使用更大的数据集:

nValues = 1000000;
value = floor(rand(nValues,1)*100000);
group = num2cell(char(floor(rand(nValues,1)*4)+'a'));
tic;
[grnum, grname] = grp2idx(group);
grvalue = accumarray(grnum,value,[],@max);
toc;

我的电脑给我的 tic/toc 时间是 0.886 秒。 (请注意,所有 tic/tock 时间均来自文件中定义的函数的第二次运行,以避免一次性生成 pcode。)

添加“矢量化”(真正的 arrayfun)一行 gridx 计算导致 tic/tock 时间为 0.975 秒。还不错,额外的调查显示大部分时间都花在了 grp2idx 调用上。

如果我们将其重新实现为一个非矢量化的简单循环,包括 gridx 计算,如下所示:

tic
[grnum, grname] = grp2idx(group);
grvalue = -inf*ones(size(grname));
gridx = zeros(size(grname));
for ixValue = 1:length(value)
tmpGrIdx = grnum(ixValue);
if value(ixValue) > grvalue(tmpGrIdx)
grvalue(tmpGrIdx) = value(ixValue);
gridx(tmpGrIdx) = ixValue;
end
end
toc

tic/toc 时间约为 0.847 秒,比原始代码略快。


更进一步,大部分时间似乎都在元胞数组内存访问中丢失了。例如:

tic; groupValues = double(cell2mat(group')); toc  %Requires 0.754 seconds
tic; dummy = (cell2mat(group')); toc %Requires 0.718 seconds

如果您最初将组名定义为数字数组(例如,我将使用上面定义的 groupValues),即使使用相同的代码,时间也会减少很多:

groupValues = double(cell2mat(group'));  %I'm assuming this is precomputed
tic
[grnum, grname] = grp2idx(groupValues);
grname = num2cell(char(str2double(grname))); %Recapturing your original names
grvalue = -inf*ones(size(grname));
gridx = zeros(size(grname));
for ixValue = 1:length(value)
tmpGrIdx = grnum(ixValue);
if value(ixValue) > grvalue(tmpGrIdx)
grvalue(tmpGrIdx) = value(ixValue);
gridx(tmpGrIdx) = ixValue;
end
end
toc

这会产生 0.16 秒的 tic/tock 时间。

关于matlab - 来自具有最大/最小值的 accumarray 的索引,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15440874/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com