Inverting permutations in Python

前端 未结 7 1198
余生分开走
余生分开走 2021-01-12 21:08

I\'m new to programming, and I\'m trying to write a Python function to find the inverse of a permutation on {1,2,3,...,n} using the following code:

def inv(s         


        
7条回答
  •  孤独总比滥情好
    2021-01-12 21:29

    Other answers are correct, but for what it's worth, there's a much more performant alternative using numpy:

    inverse_perm = np.arange(len(permutation))[np.argsort(permutation)]
    

    EDIT: and the fourth function below is even faster.

    Timing code:

    def invert_permutation_list_scan(p):
        return [p.index(l) for l in range(len(p))]
    
    def invert_permutation_list_comp(permutation):
        return [i for i, j in sorted(enumerate(permutation), key=lambda i_j: i_j[1])]
    
    def invert_permutation_numpy(permutation):
        return np.arange(len(permutation))[np.argsort(permutation)] 
    
    def invert_permutation_numpy2(permutation):
        inv = np.empty_like(permutation)
        inv[permutation] = np.arange(len(inv), dtype=inv.dtype)
        return inv
    
    x = np.random.randn(1000)
    perm = np.argsort(x)
    permlist = list(perm)
    assert np.array_equal(invert_permutation_list_scan(permlist), invert_permutation_numpy(perm))
    assert np.array_equal(invert_permutation_list_comp(perm), invert_permutation_numpy(perm))
    assert np.array_equal(invert_permutation_list_comp(perm), invert_permutation_numpy2(perm))
    %timeit invert_permutation_list_scan(permlist)
    %timeit invert_permutation_list_comp(perm)
    %timeit invert_permutation_numpy(perm)
    %timeit invert_permutation_numpy2(perm)
    

    Results:

    71.7 ms ± 859 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)
    466 µs ± 6.37 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
    21.3 µs ± 1.26 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)
    3.87 µs ± 69.6 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
    

提交回复
热议问题