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

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

様式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の連番になりました。 さて、ここからですが、

  1. ペイロードの全項目を独立のカラムにする(横に200列くらいの巨大テーブルになる)
  2. 横に伸びているペイロードを縦に並び替え、項目名をつけられるようにする

という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ファイルは曲者です。他にも色々方法がある筈ですので、試してみて下さい。