空飛ぶチンアナゴの統計解析日記

統計解析を嗜むチンアナゴのメモ帳です

続・SQLサーバーにcsvファイルを楽して読み込みたい

前回のおさらい

SQLサーバーにcsvファイルを読み込むためには
1)あきらめて直接コンソールを叩いてちまちま読み込む
2)テーブルを作成して1行ずつループで読み込ませる
のが一番無難で楽

……だと思っていた。

pandasは強い(強い)

pandas.pydata.org
pandasのto_sql()関数を使うとあっという間にデータベースに転送できる。
実際、

from sqlalchemy import create_engine
engine = create_engine('sqlite://', echo=False)

df = pd.DataFrame({'name' : ['User 1', 'User 2', 'User 3']})

df.to_sql('users', con=engine)
([https://pandas.pydata.org/docs/reference/api/pandas.DataFrame.to_sql.html:title] より)

というステップで読み込めてしまうのでとても簡単。

とはいえ欠点もある

データの型の問題

欠損値を含むデータの場合、少しめんどくさいことになる。
古いpandasを使っている場合、欠損値numpy.nanが含まれるデータはすべてすべてfloatとして扱われる*1。なので、numpy.nanを含むデータフレームを読み込ませる際には整数型のデータでもすべてfloatとして処理されてしまう。
また、tableに挿入する際は、データフレームの型が優先される。
例えば

sql = """
create table table1 (
    id int,
    name varchar(18),
    age int
)
cur.execute(sql)

と設定したとしても、データフレームのageのデータフレームの方がfloatだった場合、tableの方のageの型もfloatに変換される。
もっとも、create tableで表を作る必要性もないので、そのままto_sqlでデータサーバへ格納してしまうのが一番楽といえば楽なのだが……。

行数が膨大な時は時間が掛かる

qiita.com
うちは行数が1500万もないので多分そこまでひどくはならないだろうけど、ちょっと気をつけないといけないかも。

まとめ

なんだかんだでpandasでやるのが楽。
特に行数がそこまで多くなければpandasを使って全部クリーニングからデータサーバーへの格納まで一通りやってしまうのが一番手っ取り早いように思える。