使用索引数组在多个轴上重新排序numpy数组的最快方法

时间:2013-07-03 01:46:13

标签: python arrays sorting numpy indexing

假设我有一些数组A,其中A.shape = (x0,...,xn,r)

我希望根据相应的索引数组A{x0,...,xn},在其中ind重新排序ind.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']]]

示例:

{{1}}

1 个答案:

答案 0 :(得分: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) ... 等等。如果您调整排名,则需要重新排序,您需要按升序排列项目。你可以使用lexsort或者你可以使用numpy.ravel_multi_index来获得整数排名并在整数排名上应用argsort。如果解释不清楚,请告诉我。