HOWTO · NumPy

NumPy 셔플 두 배열

Python에서 두 개의 해당 배열을 섞는 데 사용할 수있는 세 가지 주요 메서드, sklearn.utils.shuffle() 함수, numpy.random.shuffle() 함수 및 numpy.random.permutation() 함수가 있습니다.

이 페이지의 내용

서로 관련된 두 배열을 셔플한다는 것은 두 배열의 행 순서를 함께 바꾸는 것입니다. 한 배열의 i번째 행이 다른 배열의 i번째 행에 대응한다면, 예를 들어 특성 행과 레이블이 한 쌍이라면 두 배열에 같은 순열을 적용해야 합니다. 각 배열을 따로 셔플하면 이 관계가 깨집니다. 아래 예제에서는 두 열로 된 특성 배열과 레이블 배열을 사용하며, 각 행의 값이 서로 대응하므로 정렬 상태를 쉽게 확인할 수 있습니다.

대응하는 행의 정렬을 유지하며 두 배열 셔플하기

두 배열에 동일한 행 순서를 적용하세요. 각 입력의 첫 번째 차원 길이는 같아야 합니다. 열이 여러 개인 배열에서는 동일한 순서로 행 전체를 선택하므로, 행 안의 값들은 함께 유지됩니다.

대응하는 특성 행과 레이블을 쉽게 확인할 수 있도록 고정된 순서로 이 예제를 실행합니다.

이 섹션의 코드와 표시되는 레이블 또는 출력은 영어로 유지됩니다.

import numpy as np

features = np.array([[10, 100], [20, 200], [30, 300]])
labels = np.array([1, 2, 3])
order = np.array([2, 0, 1])

print(features[order])
print(labels[order])
[[ 30 300]
 [ 10 100]
 [ 20 200]]
[3 1 2]

고정된 순서는 설명을 위한 것입니다. 무작위 순서가 필요하면 아래 셔플 방법 중 하나로 만든 순서를 사용하세요.

sklearn.utils.shuffle() 사용하기

sklearn.utils.shuffle()는 여러 배열을 받아 모두 같은 순서로 정렬한 뒤, 변수에 할당할 수 있도록 셔플된 배열을 반환합니다. scikit-learn이 설치되어 있다면 먼저 from sklearn.utils import shuffle로 함수를 가져온 다음 features_shuffled, labels_shuffled = shuffle(features, labels)를 호출하세요. 서로 관련된 배열을 모두 한 번에 전달해야 반환된 행들의 짝이 유지됩니다. scikit-learn이 이미 프로젝트에 포함되어 있다면 편리한 방법입니다. 호출할 때마다 무작위 순서는 달라질 수 있으며, 이 도우미 함수는 원본 배열을 제자리에서 바꾸는 대신 할당할 결과를 반환합니다.

이 함수의 가져오기와 호출에는 모든 Python 환경에 포함되어 있지는 않은 scikit-learn이 필요합니다. 설치되어 있다면 호출 전에 함수를 가져오고 반환된 배열 두 개를 모두 할당하세요. 이 종속성에 따른 호출은 실행된 예제가 아니라 구문으로 제시합니다. 아래의 NumPy 섹션에는 scikit-learn 없이 사용할 수 있는 실행 가능한 대안이 있습니다.

NumPy에서 공통 순열 하나 사용하기

numpy.random.permutation(features.shape[0])은 행 인덱스를 무작위 순서로 나열한 배열을 만듭니다. 이를 order에 저장한 다음 features[order]와 labels[order]를 선택하세요. NumPy 고급 인덱싱은 인덱싱된 결과를 새로 만들므로 원본 배열은 원래 순서대로 유지됩니다. 이 순서를 보관해 두면 같은 배열 배치를 다시 사용하거나, 다른 배열에도 적용하거나, 나중에 사용할 데이터와 함께 저장할 수 있습니다. 인덱스 순서를 만들고 보관하면 특정 난수 상태 인터페이스에 의존하지 않아도 됩니다.

여기서는 하나의 순서를 생성해 두 배열 모두를 인덱싱합니다. 출력되는 행 순서는 달라질 수 있지만 특성과 레이블의 짝은 그대로 유지됩니다.

이 섹션의 코드와 표시되는 레이블 또는 출력은 영어로 유지됩니다.

import numpy as np

features = np.array([[10, 100], [20, 200], [30, 300]])
labels = np.array([1, 2, 3])
order = np.random.permutation(features.shape[0])

features_shuffled = features[order]
labels_shuffled = labels[order]
print(features_shuffled)
print(labels_shuffled)

NumPy에서 공통 인덱스 배열 셔플하기

numpy.random.shuffle()는 입력 시퀀스를 제자리에서 변경합니다. order = np.arange(features.shape[0])로 인덱스 배열을 만든 뒤 np.random.shuffle(order)로 셔플하고, features[order]와 labels[order]를 사용해 두 원본 배열을 선택하세요. 이렇게 하면 원본 데이터는 그대로 두면서 행 순서를 명시적으로 다룰 수 있습니다. 같은 방식은 추가 배열에도 적용할 수 있습니다. 정렬을 맞춰야 하는 모든 배열을 동일한 셔플 인덱스로 인덱싱하세요. 제자리에서 셔플되는 것은 order뿐이며, 인덱싱 결과는 별도의 배열입니다. 다른 코드가 나중에 order를 수정할 수 있고 이 배치를 보존해야 한다면 order의 복사본을 보관하세요.

이 예제에서는 order만 변경하며, 두 원본 배열은 모두 같은 셔플 순서를 사용해 인덱싱합니다.

이 섹션의 코드와 표시되는 레이블 또는 출력은 영어로 유지됩니다.

import numpy as np

features = np.array([[10, 100], [20, 200], [30, 300]])
labels = np.array([1, 2, 3])
order = np.arange(features.shape[0])
np.random.shuffle(order)

features_shuffled = features[order]
labels_shuffled = labels[order]
print(features_shuffled)
print(labels_shuffled)

형태, 변경 동작, 재현성 확인하기

두 배열은 호환되는 첫 번째 차원을 가져야 합니다. 즉, 축 0을 따른 길이는 같아야 하지만 나머지 차원은 서로 달라도 됩니다. 예를 들어 특성 행으로 이루어진 행렬과 1차원 레이블 배열을 함께 사용할 수 있습니다. 인덱스 순서를 적용하기 전에 첫 번째 차원의 크기를 확인하여 모든 인덱스가 각 배열에서 유효하도록 하세요.

세 가지 방법은 변경되는 대상이 서로 다릅니다. sklearn.utils.shuffle()는 할당할 셔플 배열을 반환합니다. numpy.random.permutation()는 새 인덱스 순서를 반환하며, 이 순서로 배열을 인덱싱하면 재정렬된 결과가 만들어집니다. numpy.random.shuffle()는 전달받은 인덱스 배열을 수정합니다. 이 예제에서는 원본 배열 자체를 직접 셔플하지 않습니다. 어떤 방법을 사용하든 관련된 모든 배열에 같은 순서를 적용해야 대응 관계가 유지됩니다.

재현하려면 생성한 인덱스 배열을 보관했다가 원본 배열에 다시 적용하거나 데이터와 함께 저장하세요. 같은 인덱스 순서를 재사용하면 명시되지 않은 난수 상태 API에 의존하지 않고도 같은 배열 배치를 만들 수 있습니다. 새로 독립적인 셔플이 필요하면 새 순서를 생성하세요. 이 예제들은 출력되는 특정 순서를 보장하지 않습니다.