给出一个整数向量,例如:
X = [1 2 3 4 5 1 2]
我想找到一种非常快速的方法来计算具有2个元素的独特组合的数量。
在这种情况下,两个数字的组合是:
[1 2] (occurs twice)
[2 3] (occurs once)
[3 4] (occurs once)
[4 5] (occurs once)
[5 1] (occurs once)
目前我正在MATLAB中进行如下操作
X = [1 2 3 4 5 1 2];
N = length(X)
X_max = max(X);
COUNTS = nan(X_max); %store as a X_max x X_max matrix
for i = 1:X_max
first_number_indices = find(X==1)
second_number_indices = first_number_indices + 1;
second_number_indices(second_number_indices>N) = [] %just in case last entry = 1
second_number_vals = X(second_number_indices);
for j = 1:X_max
COUNTS(i,j) = sum(second_number_vals==j)
end
end
有更快/更聪明的方法吗?
答案 0 :(得分:12)
这是一种超级快速的方式:
>> counts = sparse(x(1:end-1),x(2:end),1)
counts =
(5,1) 1
(1,2) 2
(2,3) 1
(3,4) 1
(4,5) 1
您可以简单地转换为完整矩阵:full(counts)
以下是使用accumarray
的等效解决方案:
>> counts = accumarray([x(1:end-1);x(2:end)]', 1)
counts =
0 2 0 0 0
0 0 1 0 0
0 0 0 1 0
0 0 0 0 1
1 0 0 0 0
答案 1 :(得分:1)
编辑: @Amro提供了一个更好的解决方案(好吧,在绝大多数情况下更好,我怀疑如果MaxX
非常大且{{X
我的方法会更好1}}包含零 - 这是因为零的存在将排除sparse
的使用,而大的MaxX
会减慢accumarray
方法,因为它会创建一个大小为MaxX的矩阵通过MaxX)。
编辑:感谢@EitanT指出可以使用accumarray
进行的改进。
以下是我将如何解决它:
%Generate some random data
T = 20;
MaxX = 3;
X = randi(MaxX, T, 1);
%Get the unique combinations and an index. Note, I am assuming X is a column vector.
[UniqueComb, ~, Ind] = unique([X(1:end-1), X(2:end)], 'rows');
NumComb = size(UniqueComb, 1);
%Count the number of occurrences of each combination
Count = accumarray(Ind, 1);
现在,所有唯一的连续两个元素组合都存储在UniqueComb
中,而每个唯一组合的相应计数都存储在Count
中。