모양이 다른 두 개의 numpy 배열이 있지만 길이는 동일합니다 (선행 치수). 해당 요소가 계속 일치하도록 각 요소를 섞고 싶습니다. 즉, 선행 지수와 관련하여 일치하게 섞습니다.
이 코드는 작동하며 내 목표를 보여줍니다.
def shuffle_in_unison(a, b):
assert len(a) == len(b)
shuffled_a = numpy.empty(a.shape, dtype=a.dtype)
shuffled_b = numpy.empty(b.shape, dtype=b.dtype)
permutation = numpy.random.permutation(len(a))
for old_index, new_index in enumerate(permutation):
shuffled_a[new_index] = a[old_index]
shuffled_b[new_index] = b[old_index]
return shuffled_a, shuffled_b
예를 들면 다음과 같습니다.
>>> a = numpy.asarray([[1, 1], [2, 2], [3, 3]])
>>> b = numpy.asarray([1, 2, 3])
>>> shuffle_in_unison(a, b)
(array([[2, 2],
[1, 1],
[3, 3]]), array([2, 1, 3]))
그러나 이것은 어색하고 비효율적이며 느리게 느껴지며 배열의 사본을 만들어야합니다.
이것에 대해 더 좋은 방법이 있습니까? 빠른 실행과 낮은 메모리 사용이 저의 주요 목표이지만, 우아한 코드도 좋습니다.
내가 가진 또 다른 생각은 이것입니다.
def shuffle_in_unison_scary(a, b):
rng_state = numpy.random.get_state()
numpy.random.shuffle(a)
numpy.random.set_state(rng_state)
numpy.random.shuffle(b)
이것은 효과가 있지만 … 계속 작동한다는 보장이 거의 없기 때문에 조금 무섭습니다.
답변
당신의 “무서운”해결책은 나에게 무서운 것처럼 보이지 않습니다. 호출 shuffle()
난수 생성기에 대한 호출 같은 수의 같은 길이 결과의 두 시퀀스, 이들은 셔플 알고리즘에서 유일하게 “임의의”요소입니다. 상태를 재설정하면 난수 생성기에 대한 호출이에 대한 두 번째 호출에서 동일한 결과를 제공 shuffle()
하므로 전체 알고리즘이 동일한 순열을 생성합니다.
이 방법이 마음에 들지 않으면 처음부터 두 개가 아닌 하나의 배열에 데이터를 저장하고이 단일 배열에 두 개의 뷰를 만들어 현재 두 배열을 시뮬레이션하는 다른 솔루션이 있습니다. 셔플 링에는 단일 배열을 사용하고 다른 모든 용도로는보기를 사용할 수 있습니다.
예 :하자가 배열 가정 a
과 b
같은 모양을 :
a = numpy.array([[[ 0., 1., 2.],
[ 3., 4., 5.]],
[[ 6., 7., 8.],
[ 9., 10., 11.]],
[[ 12., 13., 14.],
[ 15., 16., 17.]]])
b = numpy.array([[ 0., 1.],
[ 2., 3.],
[ 4., 5.]])
이제 모든 데이터를 포함하는 단일 배열을 구성 할 수 있습니다.
c = numpy.c_[a.reshape(len(a), -1), b.reshape(len(b), -1)]
# array([[ 0., 1., 2., 3., 4., 5., 0., 1.],
# [ 6., 7., 8., 9., 10., 11., 2., 3.],
# [ 12., 13., 14., 15., 16., 17., 4., 5.]])
이제 우리는 원래의 시뮬레이션 뷰 생성 a
및 b
:
a2 = c[:, :a.size//len(a)].reshape(a.shape)
b2 = c[:, a.size//len(a):].reshape(b.shape)
의 데이터 a2
와는 b2
함께 공유됩니다 c
. 두 어레이를 동시에 섞으려면을 사용하십시오 numpy.random.shuffle(c)
.
프로덕션 코드에서는 물론 원본을 만드는 피하려고 것입니다 a
및 b
만들 즉시 전혀와 c
, a2
와 b2
.
이 솔루션은 경우에 적용 할 수 a
및 b
다른 dtypes 있습니다.
답변
NumPy의 배열 인덱싱을 사용할 수 있습니다 .
def unison_shuffled_copies(a, b):
assert len(a) == len(b)
p = numpy.random.permutation(len(a))
return a[p], b[p]
이로 인해 개별 셔플 배열이 생성됩니다.
답변
X = np.array([[1., 0.], [2., 1.], [0., 0.]])
y = np.array([0, 1, 2])
from sklearn.utils import shuffle
X, y = shuffle(X, y, random_state=0)
자세한 내용은 http://scikit-learn.org/stable/modules/generated/sklearn.utils.shuffle.html을 참조 하십시오.
답변
매우 간단한 해결책 :
randomize = np.arange(len(x))
np.random.shuffle(randomize)
x = x[randomize]
y = y[randomize]
두 배열 x, y는 이제 같은 방식으로 무작위로 섞입니다.
답변
James는 2015 년에 도움이되는 sklearn 솔루션 을 썼습니다 . 그러나 그는 불필요하게 임의의 상태 변수를 추가했습니다. 아래 코드에서는 numpy의 임의 상태가 자동으로 가정됩니다.
X = np.array([[1., 0.], [2., 1.], [0., 0.]])
y = np.array([0, 1, 2])
from sklearn.utils import shuffle
X, y = shuffle(X, y)
답변
from np.random import permutation
from sklearn.datasets import load_iris
iris = load_iris()
X = iris.data #numpy array
y = iris.target #numpy array
# Data is currently unshuffled; we should shuffle
# each X[i] with its corresponding y[i]
perm = permutation(len(X))
X = X[perm]
y = y[perm]
답변
NumPy 만 사용하여 원하는 수의 배열을 제자리에 섞습니다.
import numpy as np
def shuffle_arrays(arrays, set_seed=-1):
"""Shuffles arrays in-place, in the same order, along axis=0
Parameters:
-----------
arrays : List of NumPy arrays.
set_seed : Seed value if int >= 0, else seed is random.
"""
assert all(len(arr) == len(arrays[0]) for arr in arrays)
seed = np.random.randint(0, 2**(32 - 1) - 1) if set_seed < 0 else set_seed
for arr in arrays:
rstate = np.random.RandomState(seed)
rstate.shuffle(arr)
그리고 이렇게 사용할 수 있습니다
a = np.array([1, 2, 3, 4, 5])
b = np.array([10,20,30,40,50])
c = np.array([[1,10,11], [2,20,22], [3,30,33], [4,40,44], [5,50,55]])
shuffle_arrays([a, b, c])
몇 가지 참고할 사항 :
- 어설 션은 모든 입력 배열이 첫 번째 차원을 따라 동일한 길이를 갖도록합니다.
- 배열은 첫 번째 차원으로 제자리에서 뒤섞였으며 아무것도 반환되지 않았습니다.
- 양의 int32 범위 내의 임의의 시드
- 반복 가능한 셔플이 필요한 경우 시드 값을 설정할 수 있습니다.
셔플 후 np.split
응용 프로그램에 따라 슬라이스를 사용하여 데이터를 분할 하거나 참조 할 수 있습니다 .