파이썬으로 배열을 섞고, 파이썬으로 배열 항목 순서를 무작위로 지정하십시오.


261

파이썬으로 배열을 섞는 가장 쉬운 방법은 무엇입니까?


28
파이썬 문서의 가장 유용한 비트를 항상 우수한 SO Q & A 형식으로 마이그레이션하려면 +1하십시오.
charleslparker

1
원래 배열을 변경하지 않고 새로운 셔플 배열을 반환하는 옵션이 있습니까?
Charlie Parker

5
로 새로운 배열 (수정되지 않은)을 얻을 수 있습니다 new_array = random.sample( array, len(array) ).
Charlie Parker

답변:


464
import random
random.shuffle(array)

3
원래 배열을 변경하지 않고 새로운 셔플 배열을 반환하는 옵션이 있습니까?
Charlie Parker

@Charlie 그것은 별도의 질문으로하는 것이 좋습니다. (아마도 다른 사람이 이미 요청했습니다.)
David Z

13
난 그냥 "파이썬 셔플 배열"에 대한 검색 할 때 아이러니하게도만큼,이 페이지는 구글의 최고 히트입니다
여호수아 후버

2
@Charlie people Google은 이러한 질문에 스택 오버플로와 같은 곳에서 답변을 찾을 수 있습니다. 중복되지 않는 한 스택 오버플로를 리소스로 옵션으로 만드는 데 아무런 문제가 없습니다.
Matt

@javadba 그것은 실제로 첫 번째 질문에 대한 답을위한 것입니다. 구글에서 파고 들더라도 스택 오버플로에 대한 질문을하는 것은 아무런 문제가 없습니다. 미래의 사람들은 자신의 파기를 할 때 stackoverflow에 대한 답을 찾을 수 있습니다.
Matt


36

sklearn을 사용하여 이것을 수행하는 다른 방법

from sklearn.utils import shuffle
X=[1,2,3]
y = ['one', 'two', 'three']
X, y = shuffle(X, y, random_state=0)
print(X)
print(y)

산출:

[2, 1, 3]
['two', 'one', 'three']

장점 : 매핑을 중단하지 않고 여러 어레이를 동시에 무작위로 지정할 수 있습니다. 그리고 'random_state'는 재현 가능한 동작에 대한 셔플 링을 제어 할 수 있습니다.


1
감사합니다. 두 배열을 한 번에 섞는 것이 매우 유용합니다.
Dmitry

1
TNX를 찾고있었습니다!
nOp

2
이것은 허용 된 답변보다 더 완전하고 (종종 더 유용합니다)
javadba

21

다른 답변이 가장 쉽지만 random.shuffle메서드가 실제로 아무것도 반환하지 않는 것은 다소 성가신 일입니다 . 주어진 목록을 정렬하는 것입니다. 호출을 연결하거나 셔플 배열을 한 줄로 선언하려면 다음을 수행하십시오.

    import random
    def my_shuffle(array):
        random.shuffle(array)
        return array

그런 다음과 같은 줄을 수행 할 수 있습니다.

    for suit in my_shuffle(['hearts', 'spades', 'clubs', 'diamonds']):

7
입력을 변경하여 작동한다는 것을 상기시키기 위해 특별히 아무것도 반환하지 않습니다 . (메모리를 절약 할 수 있습니다.) 함수가 입력을 변경합니다.
John Y

2
나는 그것이 스타일 일 것 같아요. 개인적으로 나는 다른 한 쌍을 취하는 것을 달성하기 위해 한 줄을 쓸 수 있다는 사실을 선호합니다. 가능한 짧은 프로그램을 허용하는 언어가 이러한 경우 전달 된 객체를 반환하지 않는 것이 이상합니다. 입력이 제 위치에 변경되므로 random.shuffle에 대한 호출을 문제없이이 버전으로 호출 할 수 있습니다.
Mark Rhodes

12
파이썬은 실제로 가능한 한 짧은 것을 목표로하지 않습니다. 파이썬은 가독성과 표현력의 균형을 맞추는 것을 목표로합니다. 주로 매우 높은 수준의 언어이기 때문에 상당히 간단합니다. 파이썬의 자신의 내장 기능은 일반적으로 (항상)하기 위해 노력 "functionlike"이 (값을 반환하지만, 부작용이없는) 또는 "procedurelike을"이 (부작용 통해 운영하고 아무것도 반환하지 않습니다). 이것은 문장과 표현 사이의 파이썬의 엄격한 구별과 함께 진행됩니다.
John Y

좋은. 코드의 차이점을 즉시 보려면 my_shuffle로 이름을 바꾸는 것이 좋습니다.
Jabba

어쩌면 이것은 조기 최적화 일 수 있습니다 (도움이 될 수 있지만 셔플 할 필요가 명시 적으로 배열을 반환 할 필요는 없습니다). 또한 shuffle (array) 다음에 shuffle을 몇 번 사용하면 3 + n (times usage)과 달리 2 줄만 사용되지만 여러 번 사용하면 절약 할 수 있다고 생각합니다. 다음은 이러한 유형의 것을 설명하는 훌륭한 비디오입니다 (예 : 팬텀 요구 사항 및 조기 최적화) -pyvideo.org/video/880/stop-writing-classes
Aaron Newton

12

일반 파이썬 목록을 다룰 때 random.shuffle()이전 답변과 같이 작업을 수행합니다.

그러나 ndarray( numpy.array)에 random.shuffle관해서는, 원본을 깨뜨린 것 같습니다 ndarray. 예를 들면 다음과 같습니다.

import random
import numpy as np
import numpy.random

a = np.array([1,2,3,4,5,6])
a.shape = (3,2)
print a
random.shuffle(a) # a will definitely be destroyed
print a

그냥 사용하십시오 : np.random.shuffle(a)

마찬가지로 random.shuffle, np.random.shuffle현재 위치에서 배열을 섞습니다.


2
파괴 란 정확히 무엇을 의미합니까? (이 맥락에서 나는 ELL이 아니다.)
dbliss

내가 A = np.array (range (9)). reshape ([3,3]) 시도하면
Nicholas McCarthy

11

새로운 배열을 원한다면 다음을 사용할 수 있습니다 sample.

import random
new_array = random.sample( array, len(array) )

3

임의의 키로 배열을 정렬 할 수 있습니다

sorted(array, key = lambda x: random.random())

키는 한 번만 읽을 수 있으므로 정렬하는 동안 항목을 비교하는 것이 여전히 효율적입니다.

random.shuffle(array)C로 작성된 이후 더 빠를 것 같습니다.


1
이것은 배열의 각 요소에 대해 새로운 임의의 요소를 생성합니까?
javadba

@javadba 아니오, 이것은 배열을 임의 순서로 정렬하여 배열을 섞습니다
Trinh Hoang Nhu

1
죄송합니다 나는 어쩌면이 말은하지 않았다 명확하지 않았다 array나는 의미 Random요소 : 즉,이에 발생 될 수 있습니다 새로운 클래스 인스턴스마다. 나는 실제로 확실하지 않다 : 이것이 잘못된 방법 일 것입니다 : 당신은를 생성하고 호출해야합니다 . 그러나 파이썬 이 어떻게 작동 하는지 잘 모르겠다lambdarandom.random()RandomjavaRandom rng = Random()rng.nextGaussian()random.random()
javadba

1
코드가 답으로 맞을 수는 있지만 코드의 기능을 정교화하면 응답의 품질을 향상시킬 수 있습니다. 기사 확인 : 좋은 답변을 작성하려면 어떻게합니까?
LuFFy

1

이전 답변 외에도 다른 기능을 소개하고 싶습니다.

numpy.random.shufflerandom.shuffle내부 셔플 링 을 수행 할 수 있습니다. 그러나 셔플 배열을 반환하려는 경우 numpy.random.permutation사용할 함수입니다.


1

나는 내가 사용한 것을 random.shuffle()모르지만 나에게 '없음'을 반환하므로 이것을 썼다.

def shuffle(arr):
    for n in range(len(arr) - 1):
        rnd = random.randint(0, (len(arr) - 1))
        val1 = arr[rnd]
        val2 = arr[rnd - 1]

        arr[rnd - 1] = val1
        arr[rnd] = val2

    return arr

2
예, None을 반환하지만 배열이 수정되었습니다. 실제로 무언가를 반환하려면 random def shuffle (arr)을 가져옵니다. random.shuffle (arr) return arr
user781903

0
# arr = numpy array to shuffle

def shuffle(arr):
    a = numpy.arange(len(arr))
    b = numpy.empty(1)
    for i in range(len(arr)):
        sel = numpy.random.random_integers(0, high=len(a)-1, size=1)
        b = numpy.append(b, a[sel])
        a = numpy.delete(a, sel)
    b = b[1:].astype(int)
    return arr[b]

0

그주의 random.shuffle()는 반복의 원인으로 다차원 배열에 사용할 수 없습니다.

첫 번째 차원을 따라 배열을 셔플한다고 가정하면 다음 테스트 예제를 만들 수 있습니다.

import numpy as np
x = np.zeros((10, 2, 3))

for i in range(10):
   x[i, ...] = i*np.ones((2,3))

따라서 첫 번째 축을 따라 i 번째 요소는 모든 요소가 i와 동일한 2x3 행렬에 해당합니다.

다차원 배열에 올바른 셔플 기능을 사용하면 즉 np.random.shuffle(x), 원하는대로 배열이 첫 번째 축을 따라 셔플됩니다. 그러나 사용 random.shuffle(x)하면 반복이 발생합니다. len(np.unique(x))셔플 후 실행하여 이것을 확인할 수 있습니다.np.random.shuffle() 하지만 5를 사용하면 약 5를 제공하여이를 확인할 수 random.shuffle()있습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.