ナンクル力学系

学んだ事を書き連ねていこう。

Posts Tagged ‘scipy

id:salamannのためのpython講座〜FFT編〜

leave a comment »

id:salamannの卒論のために沢山FFTしてパワースペクトルのグラフ描くスクリプトをpythonで書いてみたやつ。id:salamannは卒論の謝辞に俺のこと書くべき!あとFFTのパワースペクトルについてちゃんと調べるべき!

細かい説明書こうかとも思ったけど、コメントいっぱい入れたので分かる気がする。

#!/usr/bin/env python
# -*- coding: utf-8 -*-

import scipy
import scipy.io
import scipy.fftpack
import pylab
import os

def fft_power(x, cols, sep):
    u"各列のパワースペクトルを計算する関数"
    n = len(x[0])# データの長さ
    pwr = []# 空リスト
    for c in cols:# 各列ごとにfftしてスペクトルに
        y = scipy.fftpack.fft(x[c]) * 2.0 / n
        pwr.append(# リストpwrの最後尾に追加
            scipy.absolute( y[0:n/2+2]**2 )# パワースペクトルの計算
            )
    return scipy.array(pwr)# リストからscipy.arrayに変換

def plot_all(pwr, cols, name, dir):
    u"各列ごとのプロットと、まとめてプロットをする"
    # 各列ごとのプロット
    for p,c in zip(pwr,cols):# zip([1,2,3],[a,b,c])は[(1,a),(2,b),(3,c)]を
        pylab.clf()# pyalbのキャンパスクリアー
        #fig=pylab.figure(figsize=(6,6))# 図の作成
        # x=1,2,3,... y=p[1],p[2],p[3],... でプロット
        pylab.plot(xrange(1,100),p[1:100],label="column: "+str(c))
        pylab.legend()# 凡例を出力
        pylab.savefig( os.path.join(dir,name+"_"+str(c)+".png"))
        #pylab.close(fig)
    pylab.clf()# pyalbのキャンパスクリアー
    # まとめてプロット
    #fig=pylab.figure(figsize=(6,6))# 図の作成
    for p,c in zip(pwr,cols):# zip([1,2,3],[a,b,c])は[(1,a),(2,b),(3,c)]を
        # x=1,2,3,... y=p[1],p[2],p[3],... でプロット
        pylab.plot(xrange(1,100),p[1:100],label="column: "+str(c))
    pylab.legend()# 凡例を出力
    pylab.savefig( os.path.join(dir,name+".png" ))
    #pylab.close(fig)

def main(data_name, cols, num_row, dir_suffix, sep):
    global data
    # data_nameから".csv"を取り除いて、後ろにdir_suffixをつける
    data_dir = data_name.replace(".csv","") + dir_suffix
    if not os.path.isdir(data_dir):
        # data_dirが存在してなければ作成
        os.mkdir(data_dir)
    else:
        print "Already exists: " + data_dir
    # ファイルからデータ読み込み
    print "read %s" % data_name
    data = scipy.io.read_array(data_name, separator=sep)
    stop_row = (len(data)/num_row) * num_row # stop_rowはnum_rowの倍数に(端数の行を処理しないように)
    for i in range(0, stop_row, num_row):
        print "row %d to %d." % (i, i+num_row)
        x = data[i:i+num_row].transpose()# i行からi+num_row行までスライスして転置
        print "FFT..."
        pwr = fft_power(x, cols, sep)
        print "plot..."
        plot_all(pwr, cols, data_name + "_%010d" % i, data_dir)
        # データの保存
        scipy.io.write_array(
            os.path.join(data_dir,"power_%010d.csv" % i), # data_dir以下のpower.csvのパス
            pwr.transpose(), # pwrを転置
            separator="," # カンマ区切り
            )
        # メモリ食いすぎかもしれないので開放(これでできたっけw)
        del pwr
        del x

### 以下は適当にいじってくれ
# 出力するディレクトリのsuffix
data_dir_suffix = "_data"
# FFT解析する列
data_cols=[1,2,3,4,5,6]
# FFT解析する行数の指定
data_row_num = 5000 # 10000だと1secだっけ?
# 図の作成と設定
pylab.figure(figsize=(6,6))

# 実行例 (ipythonに入って、run salamann_fft.pyとしたあと、)
# main("604_fft.csv", data_cols, data_row_num, data_dir_suffix, ",") #カンマ区切りの場合
# main("604_fft.csv", data_cols, data_row_num, data_dir_suffix, None) #スペース区切りの場合

実はこのスクリプトの最初のバージョンには問題があって、plotに時間かかるばかりかメモリを食いまくってpythonが強制終了してしまっていたたらしい。問題は、plot_allの中の今はコメントアウトしてる「fig=pylab.figure(figsize=(6,6))# 図の作成」の部分で毎回figureを作っていたから。これを無くしてpylab.figureを処理の前に実行すればよかったみたい。この関数一回実行すれば同じfigureを使いまわせるんでした><(普段使わないので。。。という言い訳w)

しかし、

  • 毎回ちゃんとpylab.closeしてるのになんでメモリ増えるの?
  • figure作るってなんでこんなコストかかるの?

とかは良く分からない。この関数をループの中で呼ばなきゃ良いんだろうが。

参考:SciPy/FFTPACK : パワースペクトル

Advertisements

Written by tkf

December 7, 2008 at 8:05 pm

Posted in PC

Tagged with ,

scipy.arrayで部分行列

leave a comment »

pythonの科学計算用ライブラリscipyのarrayの使い方が忘れやすいのでメモ.

scipy.arrayを使って行列から部分行列にアクセスする時には,

  • array[ 行開始:行終了, 列開始:列終了 ]
    または
  • array[ 行開始:行終了 ][ 列開始:列終了 ]
    ※ だたし,例えばarray[:][0:1]としても列ベクトルは取れない(array[:,0:1]なら大丈夫)ので,前者にそろえるのが良いと思います.

とします.省略可能なのは,

  • 開始の0
  • 終了が行か列の最後

ipythonでの実行例:

In [1]: import scipy

In [2]: a=scipy.array([[11,12,13],[21,22,23],[31,32,33]])

In [3]: a
Out[3]:
array([[11, 12, 13],
[21, 22, 23],
[31, 32, 33]])

In [4]: a[1:3,0:2]
Out[4]:
array([[21, 22],
[31, 32]])

In [5]: a[1:3,:2]
Out[5]:
array([[21, 22],
[31, 32]])

In [6]: a[1:,:2]
Out[6]:
array([[21, 22],
[31, 32]])

Written by tkf

May 15, 2008 at 12:00 pm

Posted in programming

Tagged with ,