配列から要素をランダムに抽出するための「インデックス」を作る
配列から要素をランダムに抽出するには、(要素の抽出に使う)インデックスをランダムにしておくだけでいい。
random_array = array[random_index]
ここではrandom_indexも配列。
以下は関連記事。
順序をランダムにしたインデックス(配列)の作り方は色々ある。比較のため処理時間を測定。いずれも0~99,999の数字を重複なしでランダムに並べた配列を生成している。
→ 所要時間:17 msec
→ 所要時間:2.6 msec
→ 所要時間:2.0 msec
→ 所要時間:2.0 msec
np.random.randint() とnp.random.choice() が一位タイ。中身の処理は一緒なんだろうか。こうしてみるとnp.random.shuffle()も大して変わらない。
かと言って抽出するもとの配列そのものをランダムにシャッフルしようとすると、その配列のサイズが大きい場合は処理が重くなるのでやらない方がいい。
要素が全てnanの配列を生成をする
最近書くpythonコードの半分以上はnumpy.ndarrayを使ってる。
numpyがなかったら仕事にならない。それくらいお世話になってる。ただ一つだけ不満というか疑問に思っているのが要素が全てnanの配列を生成をする関数がないこと。要素が全て0の配列を生成する関数 numpy.zeros() があるならnumpy.nans() があってもいいと思うけど、なぜかない。何か理由があるんだろうか。
まあとにかく、そういう関数はないので自前で作るわけで、いつも下のようなやり方をしてる。
zeros()を使って狙いのサイズの配列を作成したのちに、全要素をnanにする、という処理を行う。(本当はempty()を使った方が計算コストが低いらしいけど)
作りたい配列と同じサイズの配列があったりする場合は、zeros_like() も便利。同じサイズで要素が全て0の配列を作ってくれる。
でもやっぱりnumpy.nans()が欲しい。
nan を含む配列の要素をシフトする
配列の要素をシフトさせる関数 shift() のことを前回書いたけど、この関数は配列内の要素にnanが含まれると使えない(出力する配列の要素が全てnanになる)という欠点がある。そして残念ながら今書いてるスクリプトでは配列にnanが入るので、結局自分でコードを書いた。
前回記事はこちら。
まずは1次元配列をシフトさせるコード。
それから2次元配列をシフトさせるコード。
もっと簡単にできるよ、という方いたらぜひ教えてください。行数減らしたいです。
2次元配列をシフトさせる
pythonで配列をシフトさせたくて調べてみた。
自分でコード書いてもできるけど、pythonのことだからぴったりの関数があるんじゃないかと思って探していたら、scipy の shift() という関数を見つけた。
import numpy as np
from scipy.ndimage.interpolation import shift
xs = np.array([ 0., 1., 2., 3., 4., 5., 6., 7., 8., 9.])
shift(xs, 3, cval=np.NaN)
stackoverflow.com
上の例のように配列を右に3つシフトさせると出力はこうなる。
出力: [ nan, nan, nan, 0., 1., 2., 3., 4., 5., 6.]
逆向きに左にシフトさせる場合は、マイナスを使う。
shift(xs, -3, cval=np.NaN)
出力:
[ 3., 4., 5., 6., 7., 8., 9., nan, nan, nan]
結果は省略するけど、この関数は2次元配列にも使える。
下のようにシフト量をリストで表記すればいい。
shift(xs, [-3, 1], cval=np.NaN)
試してないけど3次元以降も使えるのかも。
ちなみに、配列内に nan が含まれる場合は、shift()は使えないみたい。
配列の中身が全てnanになってしまう。ちょっと惜しい。