Получить обычный массив из пакета Julia Permutations

#julia

#julia

Вопрос:

Я использую пакет перестановок для вычисления обратных перестановок длинного списка входных данных. Следующий код дает почти то, что я хочу:

 using Permutations

students = [[3 4 2 1]
[3 4 1 2]
[4 3 2 1]]

students_inv = [Permutation(i)'.data' for i in eachrow(students)]
 

Затем вызов students дает

 3×4 Array{Int64,2}:
 3  4  2  1
 3  4  1  2
 4  3  2  1
 

и вызов students_inv результатов

 3-element Array{LinearAlgebra.Adjoint{Int64,Array{Int64,1}},1}:
 [4 3 1 2]
 [3 4 1 2]
 [4 3 2 1]
 

Мне просто нужен массив целых чисел размером 3×4 без всякой линейной алгебры. Как я могу принудительно использовать перестановки, чтобы получить более простой результат?

Ответ №1:

Я думаю, вы ищете mapslices , и invperm :

 julia> students = [ 3  4  2  1
                    3  4  1  2
                    4  3  2  1 ];

julia> mapslices(invperm, students, dims=2)
3×4 Array{Int64,2}:
 4  3  1  2
 3  4  1  2
 4  3  2  1

julia> using Permutations

julia> mapslices(row -> Permutation(row)'.data, students; dims=2)
3×4 Array{Int64,2}:
 4  3  1  2
 3  4  1  2
 4  3  2  1
 

Обратите внимание, что для ввода литеральной матрицы вы можете просто использовать пробелы и символы новой строки (или точки с запятой), без предварительного построения строк по отдельности.

Также обратите внимание, что было бы более естественно работать со столбцами, а не со строками. И это mapslices , к сожалению, медленно для больших массивов. Этого можно избежать таким образом, или вы можете предпочесть работать с вектором векторов (или вектором кортежей) на протяжении всего пути, в зависимости от того, что еще вы делаете.

 julia> reduce(hcat, map(invperm, eachcol(permutedims(students))))
4×3 Array{Int64,2}:
 4  3  4
 3  4  3
 1  1  2
 2  2  1
 

Комментарии:

1. Там есть встроенный! Блестяще. Спасибо.

Ответ №2:

Вы можете использовать vcat функцию

 julia> students_inv = vcat((Permutation(i)'.data' for i in eachrow(students))...)
3×4 Matrix{Int64}:
 4  3  1  2
 3  4  1  2
 4  3  2  1
 

Предположим, что вместо понимания () списка использовалась нотация генератора [] .

С учетом сказанного, более эффективно использовать версию столбца, поскольку Julia является основным столбцом

 julia> students = [[3, 4, 2, 1] [3, 4, 1, 2] [4, 3, 2, 1]]
4×3 Matrix{Int64}:
 3  3  4
 4  4  3
 2  1  2
 1  2  1

julia> students_inv = hcat((Permutation(i).data for i in eachcol(students))...)
4×3 Matrix{Int64}:
 3  3  4
 4  4  3
 2  1  2
 1  2  1
 
 @btime vcat((Permutation(i)'.data' for i in eachrow($students))...)
#  1.102 μs (26 allocations: 2.31 KiB)

@btime hcat((Permutation(i).data for i in eachcol($students))...)
# 699.378 ns (15 allocations: 1.31 KiB)