雑多メモ
物忘れがひどいので、少なくとも自分がよく使う奴だけでも。
主にnumpyに絡む操作なので
import numpy as np
は既に実行した上での記述で書く。
slice関数:配列を扱うためのインデックスを抽象的に表現
例えば以下のように書くと1から無限(None指定)まで2おきのインデックスを作成。
>>> x = range(9) >>> x [0, 1, 2, 3, 4, 5, 6, 7, 8] >>> x[slice(1,None,2)] [1, 3, 5, 7]
numpyの配列2本の直積集合を出す
以下のような感じでしょうか。meshgridで計算したものをdstackとreshapeで整形して出してる。
>>> x = np.arange(0,3,1) >>> y = np.arange(0,3,1) >>> print np.dstack(np.meshgrid(x, y)).reshape(-1, 2) [[0 0] [1 0] [2 0] [0 1] [1 1] [2 1] [0 2] [1 2] [2 2]]
itertoolsを使っても書ける。ループで回すなら、こっちのほうがいいのかな。
>>> import itertools >>> x = np.arange(0, 3, 1) >>> y = np.arange(0, 3, 1) >>> for val in itertools.product(x,y): ... print val (0, 0) (0, 1) (0, 2) (1, 0) (1, 1) (1, 2) (2, 0) (2, 1) (2, 2)
numpy配列の各次元の要素数を取得するにはshape関数を使う
>>> np.shape(np.array([[1,2,3],[4,5,6]])) (2, 3) >>>
numpy配列の各要素に対して関数を適用(Rでいうapply系の書き方)
>>> f = np.vectorize(lambda x:100*x) >>> y = np.array([1,2,3]) >>> f(y) array([100, 200, 300])
二次元配列のソートにはlexsort関数を使う
以下の例だと行ごとの値を1列目→2列目と比較して、その昇順インデックスを返却。
>>> x = np.array([[1,2],[3,4],[1,3]]) >>> x array([[1, 2], [3, 4], [1, 3]]) >>> np.lexsort(x.T) array([0, 2, 1])
2次元配列に対する重複削除:unique
上述のlexsortを使った実装が以下にあって、なかなかよい。
python - Removing duplicate columns and rows from a NumPy 2D array - Stack Overflow
divmodで商・剰余のタプルを得る
同時に出るのありがたい。
以下の例だと10÷3の商(3)と剰余(1)を出してる。
>>> divmod(10,3) (3, 1)
配列のソートにはsort関数、そのインデックスが欲しければargsort関数を使う
適当に作ったnumpy.arrayをソートするって話。
ソート関数は自身の配列を変更してしまう点に注意。
>>> x = np.array(np.random.normal(size=5)) >>> x array([ 0.64180922, -0.68737811, -0.56254886, -1.05192228, 1.47702876]) >>> x.argsort() array([3, 1, 2, 0, 4]) >>> x[x.argsort()] array([-1.05192228, -0.68737811, -0.56254886, 0.64180922, 1.47702876]) >>> x.sort() >>> x array([-1.05192228, -0.68737811, -0.56254886, 0.64180922, 1.47702876])
配列(numpy.array)からの指定条件を満たすインデックスの抽出
numpy.where関数を使うといいのか、これが正しい書き方かわからんけどメモ。
詳細な使い方はリファレンス見てもよくわからん。
>>> x = np.array([1,2,3,4,5]) >>> np.where(x > 2) (array([2, 3, 4]),) >>> np.where(x == 2) (array([1]),) >>> np.where(x == 2)[0][0] 1 >>> x[1] 2
出力が多次元配列対応されているため、いちいち[0][0]と書かないと数にもっていけないのが辛い。
2次元配列でやってみると、もっとめんどい。
>>> x = np.array([[1,2,3], [4,5,6]]) >>> x array([[1, 2, 3], [4, 5, 6]]) >>> np.where(x == 3) (array([0]), array([2])) >>> np.where(x > 3) (array([1, 1, 1]), array([0, 1, 2]))
返り値をどうやって捌くかでまた美しい方法を考える必要がある。
pythonのlistだとindexメソッドでもっと素直に書けるのに。。。
>>> a = [10,15,20] >>> a.index(15) 1 >>>
似たような関数でargwhereなるものもあるらしい。
where関数の出力と比較してみると
>>> np.argwhere(x > 3) array([[1, 0], [1, 1], [1, 2]]) >>> np.where(x > 3) (array([1, 1, 1]), array([0, 1, 2])) >>>
2d-array(argwhere)かarrayのtuple(where)かが違うと言うところか。
一番よく使いそうな1次元配列の例も、よく忘れるのでもう一回書いておく。
>>> x = np.array([1,2,3,4,5]) >>> np.where(x > 3) (array([3, 4]),) >>> np.argwhere(x > 3) array([[3], [4]])
配列のインデクシング
実はこいつも良く忘れる。
特に−1は最終要素で、配列の要素は[tuple]でもアクセス可能な事を覚えておく事。
あとスライシング系も。
>>> x = np.array([[1,2,3], [4,5,6]]) >>> x[0][1] 2 >>> x[1][1] 5 >>> x[0,1] 2 >>> x[1,1] 5 >>> x[(0,1)] 2 >>> x[(1,1)] 5 >>> x[:,1] array([2, 5]) >>> x[-1,] array([4, 5, 6])