Pythonによる最適化 第4回
前回に引き続き,仮想の大規模プロジェクトにおける実装について述べる.
データを読み込んで解析したら,モデルに内在するデータの固まりをクラスとして実装しておくと後々便利だ.特に,後でプログラムを見直すときに,クラスができていると記憶を呼び起こすのが比較的楽だ.たとえば,顧客を表すクラスは,以下のように書ける.
class Customer():
def __init__(self,name,level,number,minutes):
self.name = name
self.level = level
self.number = number
self.minutes = minutes
def __str__(self):
ret="Name=%s Level= %s Number=%s Time= %s"%(self.name,self.level,self.number,int(self.minutes))
return ret
ここで,__init__はクラスオブジェクトの初期化を行うためのメソッドであり,コンストラクタと呼ばれる.上のコードでは,名前(name),レベル(levle),必要レベル(level),最低人数(number),訪問時間(time)をコンストラクタの引数として与え,クラスの属性として保管している.また,__str__は文字列を返すメソッドであり,これは内容を確認するときに役に立つ.たとえば,ある顧客オブジェクトをprint関数で出力すると,以下のように表示される.
Name=Kitty Level= B Number=3 Time= 301
行ごとにデータフレームに保管されている顧客情報から顧客クラスを生成するには,以下のように記述する.
Customers=[ ]
for i in df.index:
r = df.loc[i]
c = Customer(r["name"], r["level"],
r["number"], r["minutes"])
Customers.append( c )
ここでindexメソッドはデータフレームの行(インデックス)のリストを返す.
反復内では,各インデックスに対して,行情報にアクセスするためにloc属性を用いて行データrを抽出し,顧客クラスオブジェクトcを生成して,リストCustomersに追加している.
上のように基本となるオブジェクトの集合を保持する際のデータ構造は,リストか辞書
O(1)時間でデータにランダムアクセスする必要がある場合には辞書,順番にアクセスするときにはリストと覚えておくと良い.面倒な場合には,何でも辞書で保管しても大丈夫である.Pythonによる数理最適化のモデルについて記述した拙著「あたらしい数理最適化」ではすべて辞書で実装した例を示している.辞書だと順序が任意になるので気持ちが悪いという人には,Python 2.7で導入された順序付き辞書collectionsモジュールのOrderedDictがあるのでそれを使えば良い.
ファイルサイズが大きくデータの読み込みに時間がかかる場合には,ファイルから読んだら保管したデータ構造をバイトストリームに変換して保管しておくと良い.Pandasのデータフレームも直接バイトストリームに保管できるが,ここでは作成したクラスオブジェクトを保管しておくことにしよう.
Pythonには,pickleと呼ばれるモジュールが準備されている.たとえば,ファイル名custに,顧客オブジェクトのリストCustomersを保管するには,以下のようにする.
import cPickle
f = open('cust.dmp','w')
cPickle.dump( Customers, f )
f.close()
ちなみに上ではpickleモジュールの高速版であるcPickleを用いている.一度保管しておけば,次回からはテキストファイルから読み込まずに,直接顧客オブジェクトのリストをファイルから高速に読み込むことができる.
import cPickle
f = open('cust.dmp','r')
Customers = cPickle.load(f)
f.close()
Python言語は大変便利であるが,難点は日本語のマニュアルが不足していることと,
モジュールのインストールが面倒なことである.自分でインストールするのが面倒という方は,http://logopt.com/pc/において,簡易マニュアル付きのインストールサービスを行っているので参照されたい.
この記事が気に入ったらサポートをしてみませんか?