将大型向量中的每个元素分配给重复次数的有效方法

时间:2015-10-09 18:45:31

标签: matlab performance vectorization large-data

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

这可能是泥巴,所以这里只是我要找的一个小例子:

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的唯一元素列表,而count包含每个元素的相应数量的列表。这很快。

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

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

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

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

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

关于如何有效完成任务的任何想法?

1 个答案:

答案 0 :(得分:3)

一种方法 -

[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