1

配列AがあるとしA.shape = (x0,...,xn,r)ます。

対応するインデックスの配列に従ってA次元で並べ替えることにより、「スクランブルを解除」したいと思います。最後の次元 の順序は指定されていません。{x0,...,xn}indind.shape = (n,A.size)r

これが私がこれまで思いついた最善の方法ですが、もっとうまくできると思います。たとえば、Aコピーせずに並べ替えたビューを取得できますか?

import numpy as np
def make_fake(n=3,r=3):
    A = np.array([chr(ii+97) for ii in xrange(n**2)]
        ).repeat(r).reshape(n,n,r)
    ind = np.array([v.repeat(r).ravel() for v in np.mgrid[:n,:n]])
    return A,ind

def scramble(A,ind):
    order = np.random.permutation(A.size)
    ind_shuf = ind[:,order]
    A_shuf = A.flat[order].reshape(A.shape)
    return A_shuf,ind_shuf

def unscramble(A_shuf,ind_shuf):
    A = np.empty_like(A_shuf)
    for rr in xrange(A.shape[0]):
        for cc in xrange(A.shape[1]):
            A[rr,cc,:] = A_shuf.flat[
            (ind_shuf[0] == rr)*(ind_shuf[1] == cc)
            ]
    return A

例:

 >>> AS,indS = scramble(*make_fake())
 >>> print AS,'\n'*2,indS
[[['e' 'a' 'i']
  ['a' 'c' 'f']
  ['i' 'f' 'i']]

 [['b' 'd' 'h']
  ['f' 'c' 'b']
  ['g' 'h' 'c']]

 [['g' 'd' 'b']
  ['e' 'h' 'd']
  ['a' 'g' 'e']]] 

[[1 0 2 0 0 1 2 1 2 0 1 2 1 0 0 2 2 0 2 1 0 1 2 1 0 2 1]
 [1 0 2 0 2 2 2 2 2 1 0 1 2 2 1 0 1 2 0 0 1 1 1 0 0 0 1]] 

 >>> AU = unscramble(AS,indS)
 >>> print AU

[[['a' 'a' 'a']
  ['b' 'b' 'b']
  ['c' 'c' 'c']]

 [['d' 'd' 'd']
  ['e' 'e' 'e']
  ['f' 'f' 'f']]

 [['g' 'g' 'g']
  ['h' 'h' 'h']
  ['i' 'i' 'i']]]
4

1 に答える 1

1

これを行う 1 つの方法を次に示します。

def unscramble(A_shuf,ind_shuf):
    order = np.lexsort(ind_shuf[::-1])
    return A_shuf.flat[order].reshape(A_shuf.shape)

基本的に、各アイテムのランクは n 個のインデックスの形式で表されます。つまり、a = (0, 0)、b = (0, 1)、c = (0, 2)、d = (1, 0) ... です。等々。ランクを argsort すると、項目を昇順に並べ替える必要があります。lexsort を使用するか、または を使用numpy.ravel_multi_indexしてランクを整数として取得し、整数ランクに argsort を適用することができます。説明が明確でない場合はお知らせください。

于 2013-07-03T04:13:11.020 に答える