重新排序大矩阵或按列对值确定的特定顺序提取行

时间:2014-01-20 10:22:42

标签: matlab matrix

我需要处理一个大矩阵,我们称之为ZZ包含此格式的元素,大约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,:)这样的事情,以获得所需顺序的行矩阵。

我正在使用Z2Z的副本来提取最终的答案变量,因为我在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

1 个答案:

答案 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倍,但在您的上下文中您的机器上有更好的配置文件来验证。