2014-12-15 4 views
8

numpy 배열에서 각 열의 내용을 효율적으로 바꾸는 가장 좋은 방법은 무엇입니까?numpy에서 각 열의 내용을 바꿀 수있는 가장 좋은 방법

>>> arr = np.arange(16).reshape((4, 4)) 
>>> arr 
array([[ 0, 1, 2, 3], 
     [ 4, 5, 6, 7], 
     [ 8, 9, 10, 11], 
     [12, 13, 14, 15]]) 

>> # Shuffle each column independently to obtain something like 
array([[ 8, 5, 10, 7], 
     [ 12, 1, 6, 3], 
     [ 4, 9, 14, 11], 
     [ 0, 13, 2, 15]]) 
+2

최근의 [numpy] 개발 보드의 [discussion] (https://www.marshut.net/kpwyti/request-for-enhancement-to-numpy-random-shuffle.html)은이 기능이 추가됨을 가리 킵니다 , 잘하면. 그것은 또한 우리가'numpy' 1.9에서 이미 사용할 수있는 것으로 만족스런 방법이 없다는 것을 의미합니다. – jme

답변

6

배열이 첫 번째 축을 따라 np.random.permutation의 순서를 무작위로 바꾸어 넣습니다 (열) 기본적으로 다차원 경우 :

>>> np.random.permutation(arr) 
array([[ 4, 5, 6, 7], 
     [ 8, 9, 10, 11], 
     [ 0, 1, 2, 3], 
     [12, 13, 14, 15]]) 

그러나, 이것은을 섞어

내가 가지고있는 것은 같은 것이있다 행 인덱스와 같기 때문에 각 열에는 동일한 (임의의) 순서가 있습니다.

컬럼을 통해 루프하고 장소에 각각 셔플을 np.random.shuffle를 사용할 수 있습니다 독립적으로 각 열을 셔플의 가장 간단한 방법 :

array([[12, 1, 14, 11], 
     [ 4, 9, 10, 7], 
     [ 8, 5, 6, 15], 
     [ 0, 13, 2, 3]]) 

이을 : 예를 들어, 제공

for i in range(arr.shape[1]): 
    np.random.shuffle(arr[:,i]) 

메서드는 각 열의 순열이 제자리에서 수행되기 때문에 복사하지 않으려는 매우 큰 배열이있는 경우 유용 할 수 있습니다. 반면에, 간단한 파이썬 루프조차도 매우 느릴 수 있으며 @jme에서 제공하는 것과 같은 더 빠른 NumPy 메서드가 있습니다.

5

다음은이 일을 다른 방법 :

def permute_columns(x): 
    ix_i = np.random.sample(x.shape).argsort(axis=0) 
    ix_j = np.tile(np.arange(x.shape[1]), (x.shape[0], 1)) 
    return x[ix_i, ix_j] 

빠른 검사 :

>>> x = np.arange(16).reshape(4,4) 
>>> permute_columns(x) 
array([[ 8, 9, 2, 3], 
     [ 0, 5, 10, 11], 
     [ 4, 13, 14, 7], 
     [12, 1, 6, 15]]) 

아이디어는 임의의 숫자의 무리를 생성하는 것입니다, 다음 argsort을 각 열 내에서 독립적으로. 이것은 각 열의 인덱스의 무작위 순열을 생성합니다.

크기가 m x n 인 배열의 경우 정렬에 시간이 O(n m log m)이 걸리므로이 방법은 최적의 점근 시간 복잡성을가집니다. 그러나 파이썬의 for 루프가 꽤 느리기 때문에 실제로는 키가 큰 모든 행렬에 대해 더 나은 성능을 얻습니다.