2016-08-31 22 views
8

Tôi quan tâm đến việc sắp xếp các cột của ma trận theo các giá trị trong 2 vectơ khác. Như một ví dụ, giả sử ma trận và vectơ trông như thế này:Julia: Sắp xếp các cột của ma trận bằng các giá trị trong một véc tơ khác (tại chỗ ...)?

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 ] 

Tôi muốn sắp xếp các cột của A về giá trị tương ứng của họ trong v1v2, với v1 dùng ưu tiên hơn v2. Ngoài ra, tôi quan tâm đến việc cố gắng sắp xếp ma trận tại vị trí làm ma trận mà tôi đang làm việc rất lớn. Hiện nay, giải pháp thô của tôi trông như thế này:

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

mang đến cho kết quả mong muốn:

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

Rõ ràng cách tiếp cận của tôi không phải là lý tưởng là nó đòi hỏi tính toán và lưu trữ ma trận trung gian. Có cách tiếp cận hiệu quả hơn/thanh lịch để phân loại các cột của ma trận theo 2 vector khác không? Và nó có thể được thực hiện tại chỗ để tiết kiệm bộ nhớ?

Trước đây tôi đã sử dụng sortperm để sắp xếp một mảng theo các giá trị được lưu trữ trong một véc tơ khác. Có thể sử dụng sortperm với 2 vectơ (và tại chỗ) không?

+0

chỉ để làm rõ bạn muốn một cái gì đó như 'M [:,:] = M [:, sortperm (v1)]' nhưng sử dụng v2 khi có quan hệ? –

+0

@AlexanderMorley Có điều này là chính xác. – Landon

Trả lời

8

tôi có lẽ sẽ làm điều đó theo cách này:

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 

này nên được khá nhanh và chỉ sử dụng một vector tạm thời và một bản sao của ma trận. Nó không hoàn toàn tại chỗ, nhưng thực hiện thao tác này hoàn toàn tại chỗ là không dễ dàng. Bạn sẽ cần một hàm phân loại di chuyển các cột khi nó hoạt động, hoặc cách khác là phiên bản permute! hoạt động trên các cột. Bạn có thể bắt đầu với mã cho permute!! trong combinatorics.jl và sửa đổi nó để hoán đổi cột, sử dụng lại bộ đệm tạm thời kích thước cột đơn.

+0

Để làm điều đó tại chỗ, hãy xem hàm 'permutecols !! 'trong [PR # 21598] (https://github.com/JuliaLang/julia/pull/21598). Sau đó bạn có thể làm 'permutecols !! (M, cols)' trong đó 'cols' được tính như trên. – SGJ

Các vấn đề liên quan