August 02(Tue), 2011 Mac OS X (Lion) に python - scipy インストールする時の変更点

pip install scipy
としたところ、以下のエラーが出ました。
/usr/bin/cc -fno-strict-aliasing -O3 -w -pipe -DNDEBUG -g -fwrapv -O3 -Wall -Wstrict-prototypes -Iscipy/sparse/linalg/eigen/arpack/ARPACK/SRC -I/Users/akiraak/project/MRI-MFI/env/lib/python2.7/site-packages/numpy/core/include -c scipy/sparse/linalg/eigen/arpack/ARPACK/FWRAPPERS/veclib_cabi_c.c -o build/temp.macosx-10.4-x86_64-2.7/scipy/sparse/linalg/eigen/arpack/ARPACK/FWRAPPERS/veclib_cabi_c.o scipy/sparse/linalg/eigen/arpack/ARPACK/FWRAPPERS/veclib_cabi_c.c:4: error: expected ‘;’, ‘,’ or ‘)’ before ‘float’ scipy/sparse/linalg/eigen/arpack/ARPACK/FWRAPPERS/veclib_cabi_c.c:10: error: expected ‘;’, ‘,’ or ‘)’ before ‘float’ scipy/sparse/linalg/eigen/arpack/ARPACK/FWRAPPERS/veclib_cabi_c.c:16: error: expected ‘;’, ‘,’ or ‘)’ before ‘*’ token scipy/sparse/linalg/eigen/arpack/ARPACK/FWRAPPERS/veclib_cabi_c.c:21: error: expected ‘;’, ‘,’ or ‘)’ before ‘*’ token
そこでソースコードに #include <complex.h> を追加してあげます。
scipy/sparse/linalg/eigen/arpack/ARPACK/FWRAPPERS/veclib_cabi_c.cscipy/lib/blas/fblaswrap_veclib_c.c.srcscipy/linalg/src/fblaswrap_veclib_c.c
と、書いたけど上手くいっていないようなので試行錯誤してみる。
July 29(Fri), 2011
sqlite3 - python DBファイルで:memory:を初期化する
sqlite3.connect(':memory:') でインメモリのDBを使う場合に中身を初期化しておきたい場合があります。一つの方法としてSQLを実行する方法があります。
conn = sqlite3.connect(':memory:', isolation_level=None)
c = conn.cursor()
sqls = [
'CREATE TABLE table1 (data1 INTEGER, data2 INTEGER);',
'INSERT INTO "table1" VALUES(1, 2);',
'INSERT INTO "table1" VALUES(3, 4);'
]
for sql in sqls:
c.execute(sql)
この方法でも良いのですが、データの量が多いと時間がかかります。たとえばカラム数4千でレコード数3万の場合2分ほど。これらの全てのカラムにインデックスを張った場合2時間ほどかかりました。
これでは時間がかかりすぎます。そこでSQLを実行するのではなく、事前に作成しておいたDBファイルをそのまま読み込んで初期化する方法を紹介します。
まずapswモジュールが必要になるので、こちらから落としてインストールしておきます。
そして、DBファイルで初期化を行う手順は以下のようになります。
import sqlite3 import apsw _conn = apsw.Connection(':memory:') #1 conn = sqlite3.connect(_conn) #2 src_conn = apsw.Connection('src.db') #3 with _conn.backup("main", src_conn, "main") as backup: while not backup.done: backup.step(100) #4
- :memory: で apsw のコネクションを作成
- apsw で sqlite3 のコネクションを作成
- 初期化用のDBファイルで apsw のコネクションを作成
- 初期化用BDから :memory: へデータをコピーしていく
backup.step(100) で指定している数値は一度にコピーするページサイズです。小さくすればwhileが多く回りますが、適当な数値を入れておけば何を指定して問題ないと思います。
この方法を使うと、SQL文を実行したときにかかってた2時間が、なんと10秒まで短縮されました。
参考
sqlite3 - Python 中央値を得る集計関数を追加する
sqlite には ORACLE のように中央値を取得する集計関数 MEDIAN が無いようです。しかし以下のように自前の関数を追加することができます。
import sqlite3 class Median: def __init__(self): self.values = [] def step(self, value): self.values.append(value) def finalize(self): srtd = sorted(self.values) alen = len(srtd) return 0.5*(srtd[(alen-1)//2] + srtd[alen//2]) conn = sqlite3.connect("sqlite.db") conn.create_aggregate("median", 1, Median) cur = conn.cursor() cur.execute("select median(data1) from table1")
July 26(Tue), 2011 SQLAlchemy for Python から sqlite の connection を取得する

import sqlalchemy
engine = sqlalchemy.create_engine('sqlite:///:memory:')
conn = engine.raw_connection().connection # sqlite3.connect(':memory:') で返るオブジェクトと同じ

