【问题标题】:Efficient way to assign each element in a large vector to the number of repeats将大向量中的每个元素分配给重复次数的有效方法
【发布时间】:2016-01-07 19:28:02
【问题描述】:

我有一个包含大约 100 万个唯一值的大约 1500 万个整数 (int32) 的向量。我想找到一种计算重复整数并将它们与原始向量相关联的有效方法,以便我有一个包含每个元素计数的新向量。

这可能很清楚,所以这是我正在寻找的一个小例子:

A      = [1 1 1 3 2 5 2 1 2 6];
...
result = [4 4 4 1 3 1 3 4 3 1];

我的(不切实际的慢)实现如下(请注意,在我的 matlab 版本中, hist 不适用于整数):

A = randi(1e6,[15e6,1],'int32');
result = zeros(size(A),'int32');
[uniqueA,~,iuA] = unique(A);
counts = accumarray(iuA,1);

到目前为止,一切都很好:uniqueA 包含 A 的唯一元素的列表,而 counts 包含每个元素对应数量的列表。这相当快。

接下来是缓慢的部分。我尝试了以下方法来检索每个元素的索引:

cellIndex = arrayfun(@(x) A == x, uniqueA,'UniformOutput',false);

但这会耗尽内存(使用 16 GB 内存)并在开始交换时停止。为了避免这种情况,我尝试循环遍历唯一元素(100 万),这也很慢:

for n = 1:length(uA)
    result(A == uA(n)) = counts(n);
end

我不知道这需要多长时间,因为我已经等了半个小时了,还没有完成。

关于如何有效地完成我的任务有什么想法吗?

【问题讨论】:

  • 您是否尝试过编译程序以加快速度? Matlab 不喜欢 for 循环。
  • 我没试过编译,如果可能的话,我通常会尽量避免使用for循环。

标签: matlab performance vectorization large-data


【解决方案1】:

一种方法 -

[unq,~,idx] = unique(A);
out = changem(idx,histc(A,unq),1:max(idx))

示例运行 -

>> A
A =
     1     1     1     3     2     5     2     1     2     6
>> [unq,~,idx] = unique(A);
>> changem(idx,histc(A,unq),1:max(idx))
ans =
     4     4     4     1     3     1     3     4     3     1

这是一个更简单的版本 -

[unq,~,idx] = unique(A);
counts = histc(A,unq);
out = counts(idx)

示例运行 -

>> A
A =
     1     1     1     3     2     5     2     1     2     6
>> [unq,~,idx] = unique(A);
>> counts = histc(A,unq);
>> counts(idx)
ans =
     4     4     4     1     3     1     3     4     3     1

【讨论】:

  • 嘿,感谢您的快速回复和关于 histc 与 hist 的提示。我没有映射工具箱,但我确实尝试过使用这个octave changem code,它似乎是一个和我一样的 for 循环。我不确定“真正的”changem 代码是否相同,但是您是否尝试过在 A 中使用 1500 万个元素?我还在等待它完成。
  • @Charbucks 查看刚刚添加的更简单的版本?另外,恐怕我没有计算资源来处理数百万个元素。
  • 再次感谢,当我开始阅读 histc 的文档时,我得到的答案与您的第二个(更简单的版本)相同。与我的 1500 万个元素示例一起工作得很好:)
  • @Charbucks 太棒了!运行时是什么?
  • 我电脑上的运行时间在 4-5 秒范围内。奇怪的是,我通过使用以下方法节省了大约 1 秒: uniqueA = unique(A); [bincounts,ind] = histc(A,uniqueA);结果 = bincounts(ind);而不是使用唯一的查找索引。不知道为什么,但两者都比 for 循环(我在将近一个小时后杀死)要好得多
猜你喜欢
  • 2011-02-23
  • 2019-12-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-01-02
  • 1970-01-01
  • 2021-12-06
相关资源
最近更新 更多