[解決済み】2つのnumpy配列を同時にシャッフルするためのより良い方法
質問
形状は異なるが、同じ長さ(先頭の次元)の2つの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)
これは動作します...しかし、継続的に動作する保証がほとんどないので、少し怖いです - たとえば、numpyのバージョン間で生き残ることが保証されているようなものではなさそうです。
どのように解決するのか?
あなたのquot;scare"解決策は、私には怖いものには見えません。 呼び方
shuffle()
同じ長さの2つのシーケンスに対して、同じ回数だけ乱数発生器を呼び出すことになりますし、シャッフルアルゴリズムの唯一の要素であるquot;random"も同じです。 状態をリセットすることで、乱数発生器の呼び出しが、2回目の
shuffle()
そのため、アルゴリズム全体が同じ並べ替えを生成することになります。
もしこれが気に入らないのであれば、別の方法として、最初からデータを2つではなく1つの配列に格納し、この1つの配列に対して、今ある2つの配列を模した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.]])
これで、すべてのデータを含む1つの配列を構築することができます。
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を持ちます。
関連
-
pythonを使ったオフィス自動化コード例
-
Python関数の高度な応用を解説
-
[解決済み】DataFrameのコンストラクタが正しく呼び出されない!エラー
-
[解決済み】Python regex AttributeError: 'NoneType' オブジェクトに 'group' 属性がない。
-
[解決済み] numpyの配列と行列の違いは何ですか?どちらを使うべきですか?
-
[解決済み】NumPyで配列を列でソートする
-
[解決済み】2つのNumPy配列が等しいか、要素ごとに比較する。
-
[解決済み】2つの1次元NumPy配列の連結
-
[解決済み】numpyの配列を逆引きする最も効率的な方法
-
[解決済み] NSMutableArrayをシャッフルする最も良い方法は何ですか?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
python call matlab メソッドの詳細
-
PythonはWordの読み書きの変更操作を実装している
-
Python jiabaライブラリの使用方法について説明
-
pythonサイクルタスクスケジューリングツール スケジュール詳解
-
Pythonの@decoratorsについてまとめてみました。
-
FacebookオープンソースワンストップサービスpythonのタイミングツールKats詳細
-
[解決済み】TypeError: 系列を <class 'float'> に変換することができません。
-
[解決済み] TypeError: 'DataFrame' オブジェクトは呼び出し可能ではない
-
[解決済み】Python - "ValueError: not enough values to unpack (expected 2, got 1)" の修正方法 [閉店].
-
[解決済み】ValueError: xとyは同じサイズでなければならない