下面是一个Matlab编码问题(使用setdiff而不是相交here的一个不同版本):
一个等级矩阵A有3个cols,第一个是可能重复的用户is,第二个是可能重复的项目‘is,第三个是从用户到项目的等级,范围从1到5。
现在,我有一个用户ID( smallUserIDList )子集和一个条目ID( item ID)的子集( smallItemIDList,),然后我希望在A中找到在smallUserIDList,中被用户分级的行,并收集用户分级的项,并进行一些计算,如与smallItemIDList相交并计数结果,如下代码所示:
userStat = zeros(length(smallUserIDList), 1);
for i = 1:length(smallUserIDList)
A2= A(A(:,1) == smallUserIDList(i), :);
itemIDList_each = unique(A2(:,2));
setIntersect = intersect(itemIDList_each , smallItemIDList);
userStat(i) = length(setIntersect);
end
userStat最后,我发现配置文件查看器显示上面的循环效率很低,问题是如何用矢量化的方法来改进这段代码,但却需要for循环的帮助?
例如,:
输入
A = [
1 11 1
2 22 2
2 66 4
4 44 5
6 66 5
7 11 5
7 77 5
8 11 2
8 22 3
8 44 3
8 66 4
8 77 5
]
smallUserIDList = [1 2 7 8]
smallItemIDList = [11 22 33 55 77]输出
userStat =
1
1
2
3发布于 2015-04-08 05:04:04
阿!您需要在接受的前一个问题的解决方案中进行一个微小的编辑。有个解决办法-
[R,C] = find(bsxfun(@eq,A(:,1),smallUserIDList(:).')); %//'
mask = ismember(A(R,2),smallItemIDList(:).'); %//'# The edit was needed here
ARm = A(R,2);
Cm = C(mask);
ARm = ARm(mask);
userStat = zeros(numel(smallUserIDList),1);
if ~isempty(Cm)
dup_counts = accumarray(Cm,ARm,[],@(x) numel(x)-numel(unique(x)));
accums = accumarray(C,mask);
userStat(1:numel(accums)) = accums;
userStat(1:numel(dup_counts)) = userStat(1:numel(dup_counts)) - dup_counts;
end作为奖励,你可以编辑预分配步骤-
userStat = zeros(numel(smallUserIDList),1);有了这个更快的预分配计划-
userStat(1,numel(smallUserIDList)) = 0;在这个MATLAB Undocumented post on Pre-allocation中阅读更多关于它的信息。
https://stackoverflow.com/questions/29506283
复制相似问题