我需要处理一个大矩阵,我们称之为Z
。
Z
包含此格式的元素,大约200.000行:
2 3 6 723
3 4 7 65
3 4 8 20
3 6 9 10
4 5 9 127
4 5 10 120
4 5 11 291
4 7 14 576
5 7 8 365
5 9 11 216
6 9 12 40
.....
没有重复行。 4 th 列表示一种ID。 每行的前3列按升序排序。 行也按第1列中的值的升序排列。
如果第1列中有2行具有相同的编号,则第1列是2 nd 列中具有最小值的行。同样的原则适用于3 rd 列。这可以在这些行中看到,例如:
4 5 9 127
4 5 10 120
4 5 11 291
4 7 14 576
我需要获得下面格式的矩阵,我在行之间添加了空格,以便您可以轻松查看模式。
总而言之,我需要获得一个矩阵,其中行需要紧跟在列1和列1中的所有其他行之后。 2列2和2中的行具有相同的值对。 3.如果当前处理的行没有类似的行,则只需将其添加到矩阵中,然后在类似的事项中处理下一行。
在下面观看,列2:3
中的对(3,6),列1:2
中的对(3,6)。对(4,7)相同。对(4,8)没有匹配。
2 3 6 723
3 6 9 10
3 4 7 65
4 7 14 576
3 4 8 20
4 5 9 127
5 9 11 216
4 5 10 120
4 5 11 291
5 7 8 365
6 9 12 40
考虑到Z
的大小,我有以下代码非常慢。
在T
我正在收集Z
的行索引。我没有让它完全运行,因为它花了超过30分钟,不幸的是,这样的运行时间没用。
最后我希望我能够做一些像answer = Z2(T,:)
这样的事情,以获得所需顺序的行矩阵。
我正在使用Z2
,Z
的副本来提取最终的答案变量,因为我在while循环中修改Z
,并且我已经使用了零的行测试和已经发现的模式,希望最终答案中不会有重复。
Z2 = Z;
T = zeros(size(Z,1),1);
i = 0;
count = 1;
while size(T(T~=0),1) ~= size(Z,1)
i = i + 1;
if(isequal(Z(i,:),[0 0 0 0]))
continue;
end
p = find(ismember(Z(:,1:2),Z(i,2:3),'rows'));
T(count) = i;
if(~isempty(p))
T(count + 1:count + size(p,1)) = p;
end
Z(i,:) = 0;
Z(p,:) = 0;
count = count + size(p,1) + 1;
end
答案 0 :(得分:1)
嗯,可能的加速可能是进行以下替换:
%// p = find(ismember(Z(:,1:2),Z(i,2:3),'rows'));
p = find( all(bsxfun(@eq, Z(:,1:2), Z(i,2:3)),2) );
这是有效的,因为ismember
不是内置的,因此MATLAB的JIT编译器无法有效加速循环。
我有一种感觉可以做得更多,但首先尝试一下。在我的PC上(MATLAB R2010b,Win 7,64位),加速度大约为10倍,但在您的上下文中您的机器上有更好的配置文件来验证。