読者です 読者をやめる 読者になる 読者になる

DPCデータの分析とかやるブログ

DPCデータの分析なんかをテキトーにやってます。

PythonからSQLサーバーに接続してグラフを描いてみる

今日はPythonからPostgreのDBに接続し、データを引っこ抜いてくるところまでやってみましょう。
最後にオマケで、グラフを描画してデータの可視化まで行います。 使うライブラリは以下の通り。

  • Pandas(Pythonでデータを扱うなら必須のライブラリ)
  • Numpy(Pandasとはセット商品の数学計算ライブラリ)
  • psycopg2(PythonPostgreSQLを接続するためのライブラリ)
  • Matplotlib(一番メジャーなグラフ描画ライブラリ)
  • Seaborn(Matplotlibのグラフを見栄え良くするためのラッパー)

いきなり5つもライブラリを列挙されて面食らったかと思いますが、DPCデータを分析して可視化まで一連で行うのであれば、常用することになるライブラリです。
おまじないだと思ってコードの先頭でimportしておくのがオススメ。 なお、seabornはAnacondaに入っていません。 インストールしていない場合は、コマンドプロンプトを開きconda install seabornと入力して下さい。
これだけで導入できます。

import pandas.io.sql as psql
import psycopg2 as pg
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns


#PostgresのDBへ接続するための変数を設定
connection = pg.connect(database='ここにデータベース名を入れます',
                user='ユーザー名、postgresならデフォルトはpostgres',
                host='localhost',
                password='パスワードを入れましょう',
                port=5432)

#実際にSQL文を走らせ、データを食べさせる
data = psql.read_sql("select データ識別番号,入院年月日,実施年月日,診療科区分,分類番号, \
        sum(行為点数*行為回数) AS DPC点数 \
from d1605 \
where データ区分 = 93 \
group by データ識別番号,入院年月日,実施年月日,診療科区分,分類番号",connection)

print(data.describe()) #ここでDPC点数の全体が概観出来ます

#グラフを見やすく書式設定
sns.set(style="darkgrid")
sns.set_context("talk",1.5)


#ヒストグラムを描画
ax1 = sns.distplot(data['dpc点数'],kde=0,norm_hist=0)
plt.show() 

#箱ひげ図を描画
ax2 = sns.boxplot(x = data['診療科区分'],y=data['dpc点数'],data=data)
plt.show()

出来上がるのはこんな画像です。

f:id:stagira:20160620182317p:plainf:id:stagira:20160620182322p:plain

ひとつひとつ見ていけば、大して複雑なことはしていません。
importまみれの序盤をスルーすると、続いてconnection=SQLサーバーに接続するための変数を設定しています。
ここもお決まりの内容を入れているだけです。
data = psql.read_sql()がこのスクリプトのほぼ全てです。()の中にSQL文をぶち込み、データを引っこ抜いてきます。
得られるのはdataという名前のDataFrameです。こうしてしまえば、あとはPython側で好きなように加工できます。 .describeメソッドは、データの中身をざっと見るのに最適のメソッドで、最大値・最小値・平均値・標準偏差などが一望できます。

さて、最後にSeabornでヒストグラムと箱ひげ図を描いています。 スタイルの設定に二行、グラフの描画は一行で済んでいること注意してください。
Excel2016で描くより、こっちの方がずっと速いうえ、見た目も良いです。 (余談ですが、ヒストグラムと箱ひげ図はExcel2016以降で無いとそもそも描画すら出来ません。 マイクロソフトにしてみれば、Excelはそういうツールじゃ無い、ということでしょうし、それはその通りではありますが…)