2013/02/08

[Python] numpy の行列

numpy の行列の各要素へのアクセス方法をいろいろと試した。
まず、numpyを読み込んで、npという名前でアクセスできるようにする。

>>> import numpy as np
さらに、行列Mを作成する。
>>> M=np.matrix([[1,2,3],[4,5,6],[7,8,9]])
1行目1列目が1、1行目2列目が2である。


2行目を表示する。
>>> print M[1]
[[4 5 6]]

2行目3列目の値を表示する。
>>> print M[1,2]
6

以降、i行列j列目を(i,j)と書くこととする。

(3,2)と(1,2)の成分を取り出す。
>>> print M[[2,0],[1,1]]
[[8 2]]
(3,1)と(2,2)の成分を取り出すわけではないことに注意。

(1,3)と(2,2)、(3,1)の成分を取り出す。
>>> print M[[0,1,2],[2,1,0]]
[[3 5 7]]

(2,3)と(2,2)、(2,1)の成分を取り出す。
>>> print M[[1,1,1],[2,1,0]]
[[6 5 4]]
省略して書くこともできる。
>>> print M[1,[2,1,0]]
[[6 5 4]]
これも同様。
>>> print M[[1],[2,1,0]]
[[6 5 4]]

次の書き方はエラーとなる。
>>> print M[[1,2],[2,1,0]]
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/lib/pymodules/python2.7/numpy/matrixlib/defmatrix.py", line 305, in __getitem__
    out = N.ndarray.__getitem__(self, index)
ValueError: shape mismatch: objects cannot be broadcast to a single shape

(3,2)と(2,2)、(1,2)の成分を取り出す。
>>> print M[[2,1,0],[1,1,1]]
[[8 5 2]]

同様に省略できるが、形式が変わる。
>>> print M[[2,1,0],1]
[[8]
 [5]
 [2]]

次の3つはすべて同じ結果となる。
>>> print M[[2],1]
[[8]]
>>> print M[[2],[1]]
[[8]]
>>> print M[2,[1]]
[[8]]

しかし、[]が[]内にないと、スカラーの値が表示される。
>>> print M[2,1]
8

次の2つは同じ。
>>> print M[np.arange(3),np.arange(3)]
[[1 5 9]]
>>> print M[[0,1,2],[0,1,2]]
[[1 5 9]]

1行目と2行目を取り出す。
>>> print M[[0,1]]
[[1 2 3]
 [4 5 6]]

転置をとる。
>>> print M.T
[[1 4 7]
 [2 5 8]
 [3 6 9]]

2013/02/01

mnist.pkl.gz の読み込み方

http://deeplearning.net/tutorial/gettingstarted.html
に記載されている MNIST Dataset
http://deeplearning.net/data/mnist/mnist.pkl.gz
のデータ構造は次のようになっている。

[mnist.pkl] = [[train_set], [valid_set], [test_set]]
[*_set] = [[*_setの入力], [*_setの正解]]
[*_setの入力] = [[784個の浮動小数点の配列], ... ]
[*_setの正解] = [[0〜9の整数], ... ]

ここで、[784個の浮動小数点の配列]は28x28の手書き数字画像、
*_setはtrain_set、valid_set、test_setのいずれかである。

読み込んで端末に表示してみるコード(load.py)は次の通り。

import cPickle, gzip, numpy, sys
if len(sys.argv) != 2:
  quit()
data_index=int(sys.argv[1])
f=gzip.open('../data/mnist.pkl.gz','rb')
train_set, valid_set, test_set=cPickle.load(f)
train_set_x, train_set_y=train_set # setの中身が
for i in range(data_index,data_index+1):
  for y in range(0,28):
    for x in range(0,28):
      if train_set_x[i][y*28+x]<0.5:
        sys.stdout.write(" ")
      elif train_set_x[i][y*28+x]<0.8:
        sys.stdout.write("+")
      else:
        sys.stdout.write("*")
    sys.stdout.write("\n")
  print "correct =",train_set_y[i]
  print "--------------------------------"


8番目のデータを表示する実行例は次の通り。
$ python load.py 7





              ******+
          +**********+
         +************
          ***+++++****
                  ***+
                  ***+
                 +***
               *****+
           +++*****
         *********+
         **********
                +**
                 **
                 **
                ***
      +*       ****
     ***++++++***+
     ***********+
      +*******+
        **+



correct = 3
--------------------------------
データを読めていることが確認できる。