により、シャッフル二ても済む配列ユニゾン
-
25-09-2019 - |
質問
していても済む配列の異なる形状が同じ長さの端寸法).たいシャッフルそれぞれ、対応する要素を継続に対応すなわちシャッフルしてユニゾンに関して優れた指数。
このコードの作品を示した目標
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()
に2回目の呼び出しで同じ結果を与えることを確認します。
、別の解決策は、1列の代わりに、最初から2つの右にデータを保存し、あなたが今持っている二つの配列をシミュレートし、この単一のアレイに二つのビューを作成することです。あなたは他のすべての目的のためにシャッフルするための単一のアレイとビューを使用することができます。
例:レッツは、このような配列の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-学びます.ORG /安定/モジュール/生成/ sklearn.utils.shuffle.html の
非常に簡単な解決策ます:
randomize = np.arange(len(x))
np.random.shuffle(randomize)
x = x[randomize]
y = y[randomize]
は二つの配列は、x、yは今両方のランダム同様にシャッフルされる
ジェームズは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)
シャッフルの配列と、場所のみを使用しても済む.
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])
いくつかの注意:
- の主張を全て入力配列と同じ長さに沿って 最初の寸法となります。
- 配列のシャッフルには場所による初の寸法-何も返されます。
- ランダムseed内int32です。
- 場合は繰り返しシャッフル、シード値を設定できます。
後にシャッフルのデータを分割使用 np.split
または参照用のスライスによっての願います。
あなたのような配列を作ることができます
s = np.arange(0, len(a), 1)
それをシャッフルます:
np.random.shuffle(s)
今、あなたの配列の引数としてこのSを使用しています。同じシャッフル引数は同じシャッフルベクトルを返します。
x_data = x_data[s]
x_label = x_label[s]
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]
インプレース再編成は、接続されたリストに対して行うことができる1つの方法は、シードを使用して(それがランダムかもしれない)とシャッフルを行うためにnumpy.random.shuffleを使用しています。
# Set seed to a random number if you want the shuffling to be non-deterministic.
def shuffle(a, b, seed):
np.random.seed(seed)
np.random.shuffle(a)
np.random.seed(seed)
np.random.shuffle(b)
それはそれです。これは、まったく同じ方法で、AとBの両方をシャッフルします。これはまた、その場では常にプラスで行われます。
EDIT、np.random.seed()の使用を使用していないnp.random.RandomState代わりに
def shuffle(a, b, seed):
rand_state = np.random.RandomState(seed)
rand_state.shuffle(a)
rand_state.seed(seed)
rand_state.shuffle(b)
それを呼び出すときに単にランダムな状態を供給するために、任意のシードを渡します:
a = [1,2,3,4]
b = [11, 22, 33, 44]
shuffle(a, b, 12345)
出力:
>>> a
[1, 4, 2, 3]
>>> b
[11, 44, 22, 33]
編集:再シードに固定されたコードのランダムな状態
これを扱うことができ、よく知られた機能があります:
from sklearn.model_selection import train_test_split
X, _, Y, _ = train_test_split(X,Y, test_size=0.0)
ちょうど0にtest_sizeを設定すると分裂を回避し、データをシャッフル与えます。
それは通常、スプリット電車やテストデータに使用されているが、それはあまりにもそれらをシャッフルん。
ドキュメントからの
分割アレイまたはランダム列にマトリックスおよび試験サブセット
入力検証をラップクイックユーティリティと Aへの入力データの次(ShuffleSplit()。スプリット(X、Y))とアプリケーション 単一の分割のための呼(および必要に応じてサブサンプリングする)Aのデータ onelinerます。
と言うが、私たちは、2つの配列を持っています。
a = np.array([[1,2,3],[4,5,6],[7,8,9]])
b = np.array([[9,1,1],[6,6,6],[4,2,0]])
我々は、まず、第1の寸法を並べ替えることにより、行インデックスを取得することができる
indices = np.random.permutation(a.shape[0])
[1 2 0]
そして、高度なインデックスを使用します。 ここでは、一斉に両方の配列をシャッフルするために、同じインデックスを使用しています。
a_shuffled = a[indices[:,np.newaxis], np.arange(a.shape[1])]
b_shuffled = b[indices[:,np.newaxis], np.arange(b.shape[1])]
これは
と等価ですnp.take(a, indices, axis=0)
[[4 5 6]
[7 8 9]
[1 2 3]]
np.take(b, indices, axis=0)
[[6 6 6]
[4 2 0]
[9 1 1]]
は、その後、私は順列リストを生成するのではなく、それを示唆している、あなたは、アレイ内のすべての要素を通過し、ランダムに配列
内の別の位置にそれを交換for old_index in len(a):
new_index = numpy.random.randint(old_index+1)
a[old_index], a[new_index] = a[new_index], a[old_index]
b[old_index], b[new_index] = b[new_index], b[old_index]
この実装クヌース・フィッシャーイエーツシャッフルアルゴリズム。
の例では、これは私が何をやっているされます:
combo = []
for i in range(60000):
combo.append((images[i], labels[i]))
shuffle(combo)
im = []
lab = []
for c in combo:
im.append(c[0])
lab.append(c[1])
images = np.asarray(im)
labels = np.asarray(lab)
私は2番目の引数を取るように()のpythonのrandom.shuffleを拡張しました
def shuffle_together(x, y):
assert len(x) == len(y)
for i in reversed(xrange(1, len(x))):
# pick an element in x[:i+1] with which to exchange x[i]
j = int(random.random() * (i+1))
x[i], x[j] = x[j], x[i]
y[i], y[j] = y[j], y[i]
私は必ずシャッフルがその場で起こることをすることができる方法、および機能は、すべてが長すぎるか複雑ではありません。