EFファイル統合スクリプトをアップしました
4月分のレセプトチェックのため、EF統合ツールを使ったところ「2017年度以降のデータが入っています」と蹴られました。 あれ?と思って調べてみたら…PRISMのEF統合ツール、今年度分は6月公開予定なんですね!(白目
うーん、困りました。そういえば、去年も同じようなことがあって困ってた記憶があります。
ほじくり返すと、どうやらEF統合を自力でやろうとしてたみたいですね。
仕方ないので今年もそうしますが、去年のに少しだけ手を加えて、ヘッダを用意しなくても使えるように修正しました。
こちらのEF統合(2016).py
をご利用ください。
EファイルとFファイルのあるフォルダに置いて実行すれば、outputEF.txtが出力されます。
なお、このスクリプトの用途はあくまでDB取り込み用であり、提出仕様ではないのでご注意を。
エンコーディングがUTF-8になってるので、このまま提出すれば100%弾かれます。
Bokehで動的なグラフを描画する
そもそもBokehって?
大分前に一度紹介しましたが、PythonのグラフライブラリにBokehというものがあります。
Pythonのデータ可視化というと、matplotlibが圧倒的なデファクトになってます。
そのラッパーであるseabornも有名で、最近のPython本を見るとseabornを使う例も多いですね。
今回紹介するBokehはかなり違った出自で、HTMLを吐き出すのが特徴です。ライブラリはPython側とJavaScript側に分かれており、実際の描画はJavaScript側が行います。
また、グラフの描画レベルが2つに分かれているのも特徴です。
ローレベルのbokeh.plotting
- 折れ線グラフ、単純な散布図、棒や円などを描画できる
- D3.jsほどローレベルではないが、割りと近い感じ
- 当然自由度は高いが、これでグラフを組み上げるのは大変そう…
ハイレベルのbokeh.charts
- 既に用意された形式で、棒グラフやヒストグラム、散布図など一通り描画できる
- ユーザーサイドから見ると、seabornと似たような感覚で使える
Bokehのいいところ
グラフは動的にいじれるし、見栄えも良い。HTMLとJavaScriptなので、Webアプリにも簡単に組み込める。
Bokehの悪いところ
ライブラリの性質上、データはPython側で用意し、描画のコードを書くのだが、実際にはJavaScriptにコンバートされることになる。
Python側のデータとJavaScript側のデータは必ずしも同一ではない(!)のに注意しないといけない。
400列の巨大データから、2行だけ使ってグラフを描画するケースなどもあるので、DataFrameを全てJavaScript側に流し込むわけにはいかない、という話だけど…
こんな感じでしょうか。
後は下にJupiter Notebookを貼っておきますので、マウスでいじってみて下さい。
(前回みたいにGistも用意したんですが、JavaScriptのロードでコケました…nbviewerだと動くのは、何でなんでしょうね?)
DPC入院料を月別/科別に可視化する
さて今日も元気にJavaScriptでガンガンフロントを書いていきましょう!
…という趣旨の記事を書きそうになって正気に返ったスタゲイラです。こんばんは。
えーと。ここしばらくはこんな本を読んでました。
Reactビギナーズガイド ―コンポーネントベースのフロントエンド開発入門
- 作者: Stoyan Stefanov,牧野聡
- 出版社/メーカー: オライリージャパン
- 発売日: 2017/03/11
- メディア: 単行本(ソフトカバー)
- この商品を含むブログを見る
このままだと、ブログが「日曜プログラマのWebサイト作り」になってしまうので、路線を戻します。
今回はSQLからは離れて、既に「DPC入院料」「科名」「診療月」が入ったデータセットがあるものと仮定し、簡単な可視化をやってみましょう。
使うのはpandasのプロット機能と、seabornです。
Jupyter Notebookをそのまま載せてみました。実務でも、大体こんな感じでやってます。
実務では月別の推移を見ることが多いです。
そして、大雑把に「今月は入院料が高い」「今月はなんか低い」と分かったら、そこから細かく見ていくわけですが、真っ先に切り分けるのは診療科であることが殆どです。
このように時系列を折れ線グラフで描いたり、分布をヒストグラムや箱ひげ図で確認するのはとても重要です。
分布に異常がないかヒストグラムでチェックして、箱ひげ図で異常値がないか見る感じですね。
最後に外れ値除去を行って再び箱ひげ図を見る、なんてこともやってます。
なんでPythonでGUIアプリを書かないの?
さて、前回はElectronを使ってでっち上げたアプリケーションを公開しました。
ElectronはJavaScriptベースのライブラリです。私が普段使っているのはPythonで、JavaScriptはロクに分かっていません。
が、いざデスクトップアプリを書く段になって、選択したのはElectronでした。
PythonのGUIライブラリを使わない理由は?
当初は、PythonのGUIライブラリを覚えるべきだ、と思っていました。代表的なものとして、PyQtとKivyがあります。
早速いじってみたのですが、どちらも「テーブルを表示する」というだけのことが、妙に複雑になっていて好きになれませんでした。
例えば、テーブルのデータを変数df
に格納したとします。
Pandasでhtmlテーブルを作るのは、df.to_html()
というメソッド1行で事足りてしまいます。
PyQtでの実装は、えーと、StackOverFlowによるとこうみたいですね。
???うーん…???
QtCore.QAbstractTableModel
を継承したPandas表示用のクラスを作成し、そこにデータを流し込むみたいです。ほ、ほほう・・・
もちろん、この辺の情報は全て公式の英語ドキュメントをきっちり読み込まないといけません。
Kivyだと、うーん、recycleview
なるものを使いみたいですね。英語のドキュメントを読みましょう。
他の言語を見てみると…
ちなみに同じことをScala-swingで実装すると、まあ、最初からテーブル用のモデルがあるので、大して苦労せず実装できます。
まー、こっちはこっちで英語のドキュメントなのは変わらないんですが、swingそのものが用途に向いているんでしょう。
本来このような用途に最も向いているのは、間違いなくC#ですが、今更新たな言語と格闘する時間もありませんでした。
結局HTMLが簡単だ
まー、UI部品を組み立てていくなら、HTMLが断然簡単ですね。
見た目はCSSで幾らでも変えられるし、プレビューはブラウザですぐ見れるし…
Pythonでも、HTMLベースのGUIライブラリがあるといいんですけど。
DPCチェッカーElectron版を公開
今回はこちらです。
ZIPをダウンロードして解凍して、dpc.exeを叩いて下さい。ブラウザではなく、ちゃんとアプリケーションが走る筈です。
何だか一ヶ月ほど前に、「Windows版を作りました!」と自慢げにエントリ書いてますが、ええと、忘れて下さい。
前回のはかなり試験的なリリースで、何せファイルサイズは展開後で400MB超、exeを叩くとまずDOS窓が開き、続いてブラウザが開くという「すわ、マルウェアか!?」という挙動をしてました。
幾ら私がいい加減でも、「うーん、これアプリケーションの体を成してないよね・・・」というくらいには思います。
Electronを使ったWindowsアプリの開発について
Electronはウェブサイトをそのまんまデスクトップアプリにしてしまうライブラリです。
最近、とうとう日本語で書かれた解説書も出版され、これから盛り上がることは間違い・・・ないんじゃ・・・ないかなあ・・・(尻すぼみ
今回はズルをしていて、PythonのFlaskとよく似たライブラリ、expressでベタ移植をやってます。なのであんまり、本来のElectronの書き方ではないです。実装方法についてはあんまり参考にしないで下さい。
これからの課題は?
えーと、Python版は一時停止することになると思います。
理由は簡単で、PythonのGUIライブラリを使って、アプリケーションを作る自信が無いからです。
(これについては別エントリで詳述します)
PythonにはPyQt / Kivyといった有名なGUIライブラリがありますが、結論から言うとNode.js覚えた方が早いですね!(白目
本格的なウェブサイトや複雑なアプリケーションの構築ならいざ知らず、こういう軽量アプリなら、下手に複雑なライブラリを覚えるより、別言語で書いた方が早いと言うことは往々にしてあります。
ただ、フロントをElectronにして、バックエンドでPython走らせる方法もあるので、高度な分析機能を実装するならPython版を持ち出すかも・・・?
そこまで高度な機能なら、正直、ツールにしても仕方ない感じがしますが、まあ予定は未定ってことで・・・
「Electronではじめるアプリ開発 ~JavaScript/HTML/CSSでデスクトップアプリを作ろう」読んでます
年明けに「Webが全てにやってくるぞ!」と書いておきながら、何もしてなかったので本を買いました…
というのは冗談で、ずっとNode.jsいじってました。で、Electronでアプリ化するにあたり、適当にブログやStackOverflowの記事なんか読みつつ書いてたんですが、やっぱり英語は辛いですね!
素晴らしいタイミングで日本語の本が出たので飛びつきました。ああ、日本語だ…落ち着く…
Electronではじめるアプリ開発 ~JavaScript/HTML/CSSでデスクトップアプリを作ろう
- 作者: 野口将人,倉見洋輔
- 出版社/メーカー: 技術評論社
- 発売日: 2017/03/28
- メディア: 大型本
- この商品を含むブログを見る
が、あんまり「めでたし、めでたし」とゆー話ではありません。
JavaScriptの世界の恐ろしさ
第三章からアプリケーションを作り始めますが、いきなりReactが登場します。え、Reactってなに?という向きはここで篩い落とされるか、公式のチュートリアルを読みに行くことになるでしょう。
そうそう、ReactはJSXっていう、HTMLをJavaScriptに埋め込んだみたいなシンタックスを使うらしいですよ!当然素の状態ではブラウザで読み込めないので、トランスパイラを噛ませる必要があります。
え、トランスパイラって何ですか、って?それは、JavaScriptでないものをJavaScriptに変換するか、或いは特定のバージョンのJavaScriptを、別のバージョンのJavaScriptに変換するものです。
10年前に、JavaScriptはスクリプト言語だと学んだ気がしますが、今はコンパイラ言語になってたんですね!
はいはい、意地悪を書きましたよ。
別に今書いたようなことは、フロントエンドの世界では当然でしょう。CoffeeScriptは2010年にはもうありましたし、babelは2015年には話題になってましたからね。
しかしまあ、それでも泣き言を言うなら、JavaScriptは言語の外側が複雑過ぎる気がします。
貧弱な標準ライブラリの裏返しなのか、欠陥の多い言語設計をカバーしようとした結果なのかは分かりませんが、うーん、すごいカルチャーではあります。
ジャングル、というのがこの状況を表す最もよい言葉でしょう。
そもそも、デスクトップアプリケーションを取り巻く状況が…
とまあ、恨み言を書きましたが、別にこの本に問題があるわけではありません。
本自体は、読んでいくと今のWeb開発の景色が見えるようで、とても面白いです。日本語で書かれた唯一のElectron入門本ですし、これでReactの説明までしてたらボリュームが倍になったでしょうから、仕方ないと思います。
が、うーん…例えばC#でWPFアプリケーションを書くより、Electronの方が絶対楽かと言われると、うーん…
恐らくアプリケーションのパーツ周りを書くのはElectronの方が絶対楽ですが(だってHTMLですし)、環境作りという点ではJavaScriptの負荷は高いなあ、という感じ。
まあそれでも、C#を一から覚えるよりはJavaScriptの環境作りに苦労するほうが楽そうですけど。
ちなみに、C#でGUIアプリケーションを書くとすると、WPFが真っ先に候補に上がると思いますが、qiitaで検索すると268件しか出てきません。
Reactは604件。
そしてElectronは487件です!
みんな、どんだけデスクトップアプリが嫌いか分かりますね
様式1データを扱いやすい形に変形する
前回に引き続き様式1の操作を行ってみます。
今回は実際に様式1ファイルをいじりますが、まずは前回のおさらいから。
{('A000010', 1): '生年月日', ('A000010', 2): '性別', ('A000010', 3): '患者住所地域の郵便番号', ('A000020', 1): '入院年月日', ('A000020', 2): '入院経路', ('A000020', 3): '他院よりの紹介の有無', ('A000020', 4): '自院の外来からの入院', ('A000020', 5): '予定・救急医療入院',
前回はペイロードを扱いやすくするため、こんな感じでタプルをキーにしたディクショナリ、paydict
を作りました。
さて、では様式1のダミーデータを読み込んでみましょう。
ff1 = pd.read_csv('ff1dummy.csv')
こんな感じのデータです。
施設コード | データ識別番号 | 入院年月日 | 回数管理番号 | 統括診療情報番号 | コード | バージョン | 連番 | ペイロード1 | ペイロード2 | ペイロード3 | ペイロード4 | ペイロード5 | ペイロード6 | ペイロード7 | ペイロード8 | ペイロード9 |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
999999999 | 1111 | 2017/1/1 | 1 | 0 | A000010 | 2014/4/1 | 0 | 19800101 | 1 | 9999999 | NaN | NaN | NaN | NaN | NaN | NaN |
999999999 | 1111 | 2017/1/1 | 1 | 0 | A000020 | 2014/4/1 | 0 | 20170101 | 1 | 0 | 0 | 101 | 1 | 0 | 9 | NaN |
日本語で「ペイロード1〜9」となっているのが面倒なので、名称を変更します。
ff1.columns = ['施設コード', 'データ識別番号', '入院年月日', '回数管理番号', '統括診療情報番号', 'コード', 'バージョン', '連番', '1', '2', '3', '4', '5', '6', '7', '8', '9']
これで単なる1~9の連番になりました。 さて、ここからですが、
という2つの方法があります。1番は以前書いたことがありますし、あんまりいじりやすい形になりませんので、今回は2番で行ってみましょう。
pd.meltを使う
データ識別番号 | ペイロード1 | ペイロード2 | ペイロード3 | ペイロード4 … |
---|---|---|---|---|
ダミー | ダミー | ダミー | ダミー | ダミー |
となっているデータを、
データ識別番号 | ペイロード1 |
---|---|
データ識別番号 | ペイロード2 |
データ識別番号 | ペイロード3 |
データ識別番号 | ペイロード4 … |
こんな形に変形させます。
pandasには様々なテーブル変形方法がありますが、今回のようなケースではpd.melt
を使用します。
melted = pd.melt(ff1,id_vars = ['データ識別番号','入院年月日','コード'], value_vars=['1','2','3','4','5','6','7','8','9'],var_name = 'ペイロード',value_name = 'データ')
こうすると出来上がるのは
データ識別番号 | 入院年月日 | コード | ペイロード | データ |
---|---|---|---|---|
1111 | 2017/1/1 | A000010 | 1 | 19800101 |
1111 | 2017/1/1 | A000020 | 1 | 20170101 |
1111 | 2017/1/1 | A000010 | 2 | 1 |
1111 | 2017/1/1 | A000020 | 2 | 1 |
こんなデータです。
これで、「コード」と「ペイロード番号」のペアを並べることが出来ました! あとはこれを使って項目名を追加するだけです。
項目名カラムを追加する
melted['項目名'] = [paydict.get((k,int(y)),'') for k,y in zip(melted['コード'],melted['ペイロード'])]
新たなカラム「項目名」を作成します。「コード」と「ペイロード」のペアのキーをzipでまとめてループし、paydict
から該当する項目を抜き出します。
なお、ここでpaydict[(k,y)]
とやるとエラーになるので気をつけましょう。なんでかというと…
構造上、ペイロード項目はスカスカになっていて、例えばA000010はペイロード1~3のみに情報があり、4~9は空白となります。
paydict
には存在する項目のキーしか入っていないので、例えば(A000010,4)
をキーにした問い合わせをやると例外が返ります。
ディクショナリの`.get'メソッドを使うと、存在しないキーが指定された場合、例外を返さずにデフォルト値を返すことが出来るので、今回はそれで逃げを打ちました。
さて、出来上がりはこんな感じです。
データ識別番号 | 入院年月日 | コード | ペイロード | データ | 項目名 |
---|---|---|---|---|---|
1111 | 2017/1/1 | A000010 | 1 | 19800101 | 生年月日 |
1111 | 2017/1/1 | A000020 | 1 | 20170101 | 入院年月日 |
1111 | 2017/1/1 | A000010 | 2 | 1 | 性別 |
1111 | 2017/1/1 | A000020 | 2 | 1 | 入院経路 |
あとは出来たデータを利用していけば良いでしょう。
様式1ファイルは曲者です。他にも色々方法がある筈ですので、試してみて下さい。