2014年4月25日金曜日

arrayデータの16進パターン

numpyのarrayにはいくつかのメソッドがあります。

覚えておくとたまに便利になる機能がいくつかあります。
まず、tostringです。
動作確認しつつまとめてみます。

tostringメソッドは文字通り、arrayのデータをstringデータとして出力します。
数値を文字列に変換するわけではありません。
どういうときに使用するかというと、場合それぞれですが、
たとえば、シリアル通信やTCP/IP通信などで文字列として受け取ったデータを、数値として扱いたい場合などに使えます。
最近では、画像データの変換として使いました。


例を挙げます。
import numpy
x = numpy.arange(-3,3)
とするとxの中身は
array([-3, -2, -1,  0,  1,  2])
となります。
そこで、x
s = x.tostring()
とすると、sの中身は
'\xfd\xff\xff\xff\xfe\xff\xff\xff\xff\xff\xff\xff\x00\x00\x00\x00\x01\x00\x00\x00\x02\x00\x00\x00'
となり、16進のバイナリパターンが文字列として出力されています。
つまり、arangeで作成した段階で、4[byte](32bit)のint型として扱われ、リトルエンディアン方式で保管されているようです。

これを文字列として保存して、arrayとして戻すためには、
numpy.frombuffer( s, dtype=int )
とします。結果は、
array([-3, -2, -1,  0,  1,  2])
となります。
浮動小数点の場合はdtypeをfloatに指定します。
その他、32bitや64bit、または整数型か浮動小数点型か、符号有無などの細かい設定が必要な場合は、numpyの下に定義されている型を利用します。
たとえば

符号無整数
numpy.uint8
numpy.uint16
numpy.uint32
numpy.uint64

符号付整数
numpy.int8
numpy.int16
numpy.int32
numpy.int64

浮動小数点
numpy.float16
numpy.float32
...

複素数
numpy.complex
numpy.complex64
...

などです。



ちなみに、数値データをそれぞれ文字列に変換する場合は、いくつか方法がありますが、
a.astype( str )
とすればできます。
listとして出力するなら
map( str, a )
としてもよいかもしれません。
今度、それぞれの方法について処理時間などの比較をしてみます。



例で使用したnumpyは1.8.1 (python 2.6)を使用しています。




2014年4月24日木曜日

数理統計学・データサイエンスとpython


pythonを使って統計アルゴリズムを記述することができます。
現在、統計アルゴリズムをコーディングする上でいくつかの比較的簡便な方法が開発されてきました。統計言語Sを基にしたR言語もその一つです。

ここでは最近急速に発展してきたpythonを使った方法について考察してみます。
最近の流れとしては大規模データ、いわゆるビッグデータの分析に注目が集まっているようです。
pythonはこれまでにも書いてきたようにスクリプト言語で基本インタプリタですので、書き方によっては計算時間がネックになってしまうことがあります。
さらには、もともと統計分析を目的として開発されたSまたはR言語のような機能の豊富さには負けます。
しかし、pythonはそれを上回るほどの開発効率やソースコードの簡潔さが特徴で、ライブラリも多岐にわたるため応用範囲が広いという利点があります。

科学技術計算で使うためのライブラリとしては、有名なものだけでも

  • Numpy
  • Scipy
  • Sklearn
  • Pandas
  • Jubatus

などがあります。

Numpyについてはこれまでも何回か説明してきましたが、統計に限らず数値演算の基本的な機能を提供します。
Numpyのもっとも重要な機能はArrayだと思います。
Arrayというのはつまり配列ですが、python標準のlistより、ベクトル的な計算を意識したもので、これを効果的に使うことにより、効率的な計算が可能です。
NumpyにはMatrixという型もあります。
Matrixを使うと行列演算が簡単にかけるので便利ではありますが、
Arrayの方が使い勝手が良いと思います。


ScipyはNumpyではカバーしきれなかった科学技術寄りの機能を実現しています。
たとえば、統計アルゴリズムの例でいうと、乱数発生はNumpyの機能が使えます。つまり、
numpy.random.randn(100)
などとすると100個の正規乱数がnumpy.array形式で生成されます。
しかし、正規分布の確率密度関数のグラフが書きたいとなれば、
scipy.statsの機能が使えます。

import numpy
import scipy.stats
p = scipy.stats.norm.pdf( numpy.arange(-3,3,0.1) )

とすれば、pに-3から3までの正規密度関数の値が入ります。
正規分布のほかにもcauchy分布やgammaやvon misesなどの分布もあります。
統計の論文に出てきそうな標準的確率分布はあらかたあります。


残りのライブラリの説明はまた今度します。
興味があれば、それぞれググってみてください。







2014年3月17日月曜日

C言語との連携 ctypes


pythonは高機能で大変便利ですが、処理が遅いので困る場合があります。
そういう場合は、いろいろと工夫して高速化する方法があります。

ctypesによるDLLの利用はその高速化手法の一つです。
つまり、C言語(など)でDLLを作成して、pythonから読み込みます。
そのDLLを呼びだすためのライブラリがctypesです。

import ctypes

d = ctypes.cdll.LoadLibrary("libx.dll")


C言語と言いましたが、実際C++で作成しても構いません。
但し、呼びだす関数部分はC言語の方式で書かなければなりません。

つまり裏側ではC++のclass定義やインスタンスを生成しても構いませんが、
pythonから呼び出す部分は

extern "C"

などとしてC言語方式で、関数にしなければならないということです。




2014年3月13日木曜日

グラフ

グラフはプレゼンするうえでは必須で、見やすいグラフをどうやって作るかは重要な課題です。
Excelは最近のバージョンで少し見やすくなりましたが、昔はかなりひどいものでした。

これまでMATLABを使ったりRを使ったりしていましたが、
現在は
pythonのグラフ描画ライブラリであるmatplotlibを使っています。
結構グラフがきれいに描画できるのでお勧めです。

import matplotlib.pyplot as ppl
import numpy

t = numpy.arange(100)
ppl.plot( t, numpy.sin( t ) )

ppl.show()




こんな感じで簡単にグラフが描画できます。
行列の値に応じて色分けして表示する場合は、
a = numpy.random.randn(10,15)
ppl.pcolor( a )
とすると表示できます。




2014年3月12日水曜日

並列処理

pythonによるプロセスベースの並列処理に関するメモです。
ライブラリのmultiprocessingを使います。



import multiprocessing as mul

def getLL( d ):
    return -d*d/2

pool = mul.Pool( processes=2 )

data = [ 0.5, 0.2, 0.1 ]
res = pool.map( getLL, data )



getLLは自分で定義した関数です。
dataはリストで、この中身が一つずつgetLLに渡されます。
ここでこの関数は
プロセス毎に実行されます。
ただし、一度に流れるプロセスは最初に決めた値(processes=2)です。

これで簡単に並列計算することができます。
関数への引数は一つしか受け付けないようです。


2014年3月10日月曜日

OpenCV3: WEBカメラ画像の取得

pythonでOpenCVライブラリを利用し、画像処理をします。
今回は単純にWEBカメラ画像を取得して表示するプログラムを書いてみます。


import cv2

cv2.namedWindow('CAMERA')
v = cv2.VideoCapture(0)
v.grab()
im = v.read()
cv2.imshow( 'CAMERA', im[1] )
key = cv2.waitKey(0)


以上で終了です。
C言語などに比べると驚くほど短いです。

これを実行すると、WEBカメラから取得した画像をウィンドウに表示します。
ウィンドウ上でエンターキー入力するとウィンドウが消えてプログラムが終了します。


継続的にカメラ画像を取得して表示したい場合はgrabからwaitKeyまでをループさせてください。
waitKey命令を入れないと画面が更新されません。
waitKeyの引数はキーの入力待ち時間[msec]です。
ループさせると、カメラ画像を継続的に取得表示します。
つまりカメラの映像を、そのまま表示する事ができます。

ソースコードは

import cv2

cv2.namedWindow('CAMERA')
v = cv2.VideoCapture(0)
key = 0
while key != 32:
  v.grab()
  im = v.read()
  cv2.imshow( 'CAMERA', im[1] )
  key = cv2.waitKey(1000)


こんな感じです。
今度はスペースキーで終了します。

スペースキーに32という番号が振られているので、key=32になったらループから抜け出すようになっています。


実行すると
指定したCAMERAと言う名前のウィンドウが出てきます。







2014年3月5日水曜日

コマンドライン1行でpythonのコマンドを実行する方法

これもたまにしか使わないので、書いておかないとよく忘れてしまいます。

linuxなどの端末(terminal)で、スクリプトファイルを作るまでもない些細なことで、
スクリプトなら簡単にできる処理がしたいとします。
且つ、linuxコマンドだけでは複雑すぎて面倒な処理などに、1行スクリプトが効果を発揮します。

例をお見せします。

python -c 'print "\n".join([ "mv %d %d.jpg" % ( i, i ) for i in range(5) ])'

以前紹介したリスト内包表記を使っています。
これを実行すると下のように出力表示されます。

mv 0 0.jpg
mv 1 1.jpg
mv 2 2.jpg
mv 3 3.jpg
mv 4 4.jpg

こうしてコマンド文字列を生成することができます。
文字列がうまくできていることを確認できたら今度は

python -c 'print "\n".join([ "mv %d %d.jpg" % ( i, i ) for i in range(5) ])' | bash

などとして、bashの標準入力に流し、実際に実行できます。
こうしてpythonの機能を使って、効率よく処理できます。
挙げた例でいうと、順番に番号が付けられたファイルをいっぺんに名前を変更するときなどに便利です。


python を-cというオプションで実行するとそのあとの文字列が実行されます。
細かいことはググればヘルプなども出てきます。
実はこれはpearlやrubyなど他のスクリプト言語でも似たようなことが出来ますが、
pythonは文法が少し違うので、慣れが必要です。