Initializing numpy matrix to something other than zero or one

立体地形図(1)(6)の中でさ、nan で fill したかったわけさ、ほんとはね。

だけどちっちゃいからじぶんのことさっちゃんて…

タイトルの通りで、numpy.zeros, numpy.ones, numpy.eye, numpy.empty というふうに、単位行列を作るのに便利なものと未初期化(いわゆる random fill)で作るものはあるんだけれど、NaN で初期化するのはないの。

例のごとくStackOverflowより。NumPy 1.8+ 限定だと、これがいいね:

1 >>> import numpy as np
2 >>> np.full((2, 3), np.nan)
3 array([[ nan,  nan,  nan],
4        [ nan,  nan,  nan]])
5 >>> 

こいつぁ便利。損してたな。

記憶では 1.9 になって2年くらい経ってると思う。わたしは Windows では 1.9.2rc1 を使ってる。ので今更 1.7 のことを心配しなくていいとは思うけれど、仮に 1.8 以前ならStackOverflowにある通り、

 1 >>> # one-liner. faster than fill but slower than the assignment method
 2 >>> np.empty((2, 3)) * np.nan
 3 array([[ nan,  nan,  nan],
 4        [ nan,  nan,  nan]])
 5 >>> 
 6 >>> # with fill
 7 >>> a = np.empty((2, 3))
 8 >>> a.fill(np.nan)
 9 >>> a
10 array([[ nan,  nan,  nan],
11        [ nan,  nan,  nan]])
12 >>> 
13 >>> # with assignment method
14 >>> a = np.empty((2, 3))
15 >>> a[:] = np.nan
16 >>> a
17 array([[ nan,  nan,  nan],
18        [ nan,  nan,  nan]])

ね。(こちらは当然知っていたんだけれど、一行で書けないのがなんかイヤで、zeros 使ってたの、アタシ。)

ちなみに StackOverflow での議論は「ワンライナーや否や」が若干強調され過ぎているけど、numpy の場合特に、破壊的か非破壊的か(インプレイス演算か否か)が大事で、これを常に意識しないと時としてハマります。結構慣例に反するような破壊的操作になることが多いんだよね、numpy, scipy。(なんでかってのは、fortran 流儀をルーツにしてるのが多いからね。)