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

Lan*_*don 8 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  ]
Run Code Online (Sandbox Code Playgroud)

我想的排序列A在其相应的值方面v1v2v1优先于v2.另外,我很感兴趣,试图矩阵排序的地方,因为我一起工作的矩阵是非常大的.目前,我的原始解决方案如下:

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

这给出了期望的结果:

3x6 Array{Int64,2}:
  4   6   1   5   2   3
 10  12   7  11   8   9
 16  18  13  17  14  15
Run Code Online (Sandbox Code Playgroud)

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

以前我用于sortperm根据存储在另一个向量中的值对数组进行排序.是否可以使用sortperm2个矢量(和就地)?

Jef*_*son 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
Run Code Online (Sandbox Code Playgroud)

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