小能豆

根据另一个数组的大小顺序获取一个数组的排列

shell

给定两个数组

julia> a = [30, 14, 10, 21] 
julia> b = [2, 8, 24, 1]

我想获得排列索引 ( perm_ixs) b,使得 的元素大小排序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

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

阅读 275

收藏
2024-02-23

共1个答案

小能豆

您的方法已经很接近了,但是可以稍微简化一下,避免使用循环和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函数的结果,简化了代码逻辑。

2024-02-23