MATLAB - 选举对应于相同种类
一种n×m
矩阵A
元素的总和的矩阵和矢量n×1
是Date
功能S = sumdate(A,Date)
的输入端。
该函数返回n×m
向量S
,使得S
中的所有行对应于同一日期的A
行的总和。
例如,如果
A = [1 2 7 3 7 3 4 1 9
6 4 3 0 -1 2 8 7 5]';
Date = [161012 161223 161223 170222 160801 170222 161012 161012 161012]';
然后我希望返回的矩阵S
是
S = [15 9 9 6 7 6 15 15 15;
26 7 7 2 -1 2 26 26 26]';
-
因为元素
Date(2)
和Date(3)
是相同的,我们有-
S(2,1)
和S(3,1)
都等于的A(2,1)
和A(3,1)
-
S(2,2)
和S(3,2)
都等于的A(2,2)
和A(3,2)
总和的总和。
-
-
由于元件
Date(1)
,Date(7)
,Date(8)
和Date(9)
是相同的,我们有S(1,1)
,S(7,1)
,S(8,1)
,S(9,1)
等于的A(1,1)
,A(7,1)
,A(8,1)
,A(9,1)
总和
S(1,2)
,S(7,2)
,S(8,2)
,S(9,2)
等于的A(1,2)
,A(7,2)
,A(8,2)
总和,A(9,2)
同为S([4,6],1)
和S([4,6],2)
作为元件Date(5)
不重复,所以S(5,1) = A(5,1) = 7
和S(5,2) = A(5,2) = -1
。
我写的代码到目前为止
这是我对这个任务的代码试试。
function S = sumdate(A,Date)
S = A; %Pre-assign S as a matrix in the same size of A.
Dlist = unique(Date); %Sort out a non-repeating list from Date
for J = 1 : length(Dlist)
loc = (Date == Dlist(J)); %Compute a logical indexing vector for locating the J-th element in Dlist
S(loc,:) = repmat(sum(S(loc,:)),sum(loc),1); %Replace the located rows of S by the sum of them
end
end
我使用A
和Date
具有这些属性测试它在我的电脑上:
size(A) = [33055 400];
size(Date) = [33055 1];
length(unique(Date)) = 2645;
花了我的电脑约1.25秒内执行任务。
此任务在我的项目中执行了数十万次,因此我的代码太耗时。如果我能消除上面的for循环,我认为性能会提高。
我发现了一些内置函数,它们可以执行accumarray
或cumsum
等特殊类型的总和,但我仍然对如何消除for循环没有任何建议。
我将不胜感激您的帮助。
你可以用accumarray
来做到这一点,但是你需要生成一组行和列的下标到A
来做到这一点。具体方法如下:
[~, ~, index] = unique(Date); % Get indices of unique dates
subs = [repmat(index, size(A, 2), 1) ... % repmat to create row subscript
repelem((1:size(A, 2)).', size(A, 1))]; % repelem to create column subscript
S = accumarray(subs, A(:)); % Reshape A into column vector for accumarray
S = S(index, :); % Use index to expand S to original size of A
S =
15 26
9 7
9 7
6 2
7 -1
6 2
15 26
15 26
15 26
注1:这将使用更多的内存比您的循环液(subs
将元素作为A
数的两倍),但可以给你一个显著加速。
注#2:如果您使用的是比R2015a更早的MATLAB版本,您将不会有repelem
。相反,你可以替换使用kron
(或其他解决方案here之一)该行:
kron((1:size(A, 2)).', ones(size(A, 1), 1))
注:你应该使用'.''转置矩阵,而不是共轭复数''' – Wolfie
非常感谢你为您的编辑和建议。你是对的,我应该使用'。''来代替,因为在这种情况下我不需要任何共轭,输入包含复数。 – Leba
没问题,我最终为你做了编辑,但在将来尝试使用“代码格式化”而不是**粗体格式**时,如果在文本中有代码,它会使事情变得更加清晰 – Wolfie