给定两个数组
julia> a = [30, 14, 10, 21] julia> b = [2, 8, 24, 1]
我想获得排列索引 ( perm_ixs) b,使得 的元素大小排序b对应于 的元素大小排序a。
perm_ixs
b
a
julia> perm_ixs = [3, 1, 4, 2] julia> b[perm_ixs] 4-element Vector{Int64}: 24 2 1 8
从上面可以看出,中的perm_ixs元素是第三大元素,并且 中 的第三大元素位于索引 处。因此,在 permuted 中,第二个元素应该有一个 value 。我当前的方法如下所示,看起来相当幼稚。有没有更有效的方法来做到这一点?2``b``a``14``2``b``2
2``b``a``14``2``b``2
julia> function get_size_based_permutation(a, b) @assert length(a) == length(b) # Get vectors ranking the size of elements relative to others in the vector # where size 1 is the largest element and size n is the smallest @show sizes_a = invperm(sortperm(a; rev=true)) @show sizes_b = invperm(sortperm(b; rev=true)) # Map the ix of the matching size element in one array to the # linearly ordered ixs of the other array p = collect(1:length(sizes_a)) for (ix, size_of_ele_in_b) in enumerate(sizes_b) matching_size_ix = findfirst(ele -> ele == size_of_ele_in_b, sizes_a) p[matching_size_ix] = ix end return p end julia> a = [30, 14, 10, 21] julia> b = [2, 8, 24, 1] julia> perm_ixs = get_size_based_permutation(a, b) sizes_a = invperm(sortperm(a; rev = true)) = [1, 3, 4, 2] sizes_b = invperm(sortperm(b; rev = true)) = [3, 2, 1, 4] 4-element Vector{Int64}: 3 1 4 2 julia> b[perm_ixs] 4-element Vector{Int64}: 24 2 1 8
您的方法已经很接近了,但是可以稍微简化一下,避免使用循环和findfirst函数。您可以直接利用sortperm函数的返回结果来获得排列索引。以下是一个简化版本的实现:
findfirst
sortperm
function get_size_based_permutation(a, b) @assert length(a) == length(b) # 获取a和b数组元素大小的排序索引 perm_a = sortperm(a; rev=true) perm_b = sortperm(b; rev=true) # 将b数组元素的排序映射到a数组元素的排序 perm_ixs = [findfirst(x -> x == i, perm_a) for i in perm_b] return perm_ixs end # 示例 a = [30, 14, 10, 21] b = [2, 8, 24, 1] perm_ixs = get_size_based_permutation(a, b) println(perm_ixs) println(b[perm_ixs])
这样做的好处是不需要额外的循环,而是直接利用了sortperm函数的结果,简化了代码逻辑。