朱莉娅:用另一个向量中的值(就地......)对矩阵的列进行排序?

时间:2016-08-31 07:43:28

标签: arrays sorting matrix julia

我感兴趣的是根据2个其他向量中的值对矩阵的列进行排序。例如,假设矩阵和向量看起来像这样:

M  = [ 1   2   3   4   5   6  ; 
       7   8   9   10  11  12 ; 
       13  14  15  16  17  18 ]

v1 = [ 2 , 6 , 6 , 1 , 3 , 2  ]
v2 = [ 3 , 1 , 2 , 7 , 9 , 1  ]

我想根据Av1中的相应值对v2的列进行排序,其中v1优先于v2。此外,我有兴趣尝试对矩阵进行排序,因为我使用的矩阵非常大。目前,我的原始解决方案如下:

MM = [ v1' ; v2' ; M ] ; ## concatenate the vectors with the matrix
MM[:,:] = sortcols(MM , by=x->(x[1],x[2])) 
M[:,:] = MM[3:end,:]

给出了期望的结果:

3x6 Array{Int64,2}:
  4   6   1   5   2   3
 10  12   7  11   8   9
 16  18  13  17  14  15

显然,我的方法并不理想,它需要计算和存储中间矩阵。是否有一种更有效/更优雅的方法,用2个其他向量对矩阵的列进行排序?是否可以到位来节省内存?

以前我使用sortperm根据存储在另一个向量中的值对数组进行排序。是否可以将sortperm与2个向量(和就地)一起使用?

1 个答案:

答案 0 :(得分:8)

我可能会这样做:

julia> cols = sort!([1:size(M,2);], by=i->(v1[i],v2[i]));

julia> M[:,cols]
3×6 Array{Int64,2}:
  4   6   1   5   2   3
 10  12   7  11   8   9
 16  18  13  17  14  15

这应该非常快,并且只使用一个临时向量和矩阵的一个副本。它并非完全就位,但完全就地完成此操作并不容易。您需要一个排序功能,可以在列工作时移动列,也可以使用适用于列的permute!版本。您可以从combinatorics.jl中的permute!!代码开始,并将其修改为置换列,重用单个列大小的临时缓冲区。