NDBオープンデータ(二次医療圏別収縮期血圧)のクリーニング
第7回NDBオープンデータのデータクリーニングを行ったソースコードを載せます。
今回の元データは収縮期血圧 二次医療圏別性年齢階級別分布です。
元データは以下のようなエクセルファイルです。
データ解析しやすいように、血圧のクラスは列に設定しました。
下のコードの年齢と性別の部分を変えれば、自由にエクセルファイルに出力が可能です。
例として、40~44歳の男性の二次医療圏別性年齢階級収縮期血圧分布をデータクリーニングしてみます。
〜 import numpy as np import pandas as pd # 収縮期血圧のデータ読み込み df_sbp = pd.read_excel("SBP_2ndmed_7ndb.xlsx") # titleを取得 df_sbp_title = df_sbp.columns[0] # 検査データの単位を取得 bp_sbp_unit = df_sbp.iloc[0, 1] df_sbp = pd.read_excel("SBP_2ndmed_7ndb.xlsx", skiprows =3) # 列名の変更 df_sbp = df_sbp.drop(df_sbp.index[[0]]) df_sbp = df_sbp.rename(columns={"Unnamed: 0": "prefecture", "Unnamed: 1": "2nd_med_area_code", "Unnamed: 2": "2nd_med_area", "Unnamed: 3": "sbp_class" }) # 都道府県などの欠損値を穴埋め df_sbp = df_sbp.fillna(method="ffill") # 二次医療圏判別不可を除外 df_sbp = df_sbp[df_sbp.loc[:, "prefecture"] != "二次医療圏判別不可"] # 男性と女性のデータを区別 # 男性 rename_cols = ["40~44歳", "45~49歳", "50~54歳", "55~59歳", "60~64歳", "65~69歳", "70~74歳", '中計'] df_sbp = df_sbp.rename(columns={rename_col: f"{rename_col}_男性" for rename_col in rename_cols}) # 女性 rename_cols_women = [f"{i}.1" for i in rename_cols] df_sbp = df_sbp.rename(columns={rename_col_woman: rename_col_woman.replace(".1", "") for rename_col_woman in rename_cols_women}) df_sbp = df_sbp.rename(columns={rename_col: f"{rename_col}_女性" for rename_col in rename_cols}) # 今回は男性の40~44歳のデータを抽出 df_sbp = df_sbp.loc[:, ["prefecture","2nd_med_area_code", "2nd_med_area", "sbp_class", "40~44歳_男性"]] # 180overだけprefectureなどの列を残し、他のdfは血圧の列だけにして、後でmergeで結合 # 2nd_med_area_codeで結合しないと、同じ名前の二次医療圏があってdfの行数がおかしくなる # 180_over df_sbp_180_over = df_sbp[df_sbp.loc[:, "sbp_class"] == "180以上"].rename(columns={"40~44歳_男性": "180以上"}).drop("sbp_class", axis=1) # 160-180 df_sbp_160_180 = df_sbp[df_sbp.loc[:, "sbp_class"] == "160以上180未満"].rename(columns={"40~44歳_男性": "160以上180未満"}).drop(["prefecture","2nd_med_area", "sbp_class"], axis=1) # 140-160 df_sbp_140_160 = df_sbp[df_sbp.loc[:, "sbp_class"] == "140以上160未満"].rename(columns={"40~44歳_男性": "140以上160未満"}).drop(["prefecture","2nd_med_area", "sbp_class"], axis=1) # 130-140 df_sbp_130_140 = df_sbp[df_sbp.loc[:, "sbp_class"] == "130以上140未満"].rename(columns={"40~44歳_男性": "130以上140未満"}).drop(["prefecture","2nd_med_area", "sbp_class"], axis=1) # 120-130 df_sbp_120_130 = df_sbp[df_sbp.loc[:, "sbp_class"] == "120以上130未満"].rename(columns={"40~44歳_男性": "120以上130未満"}).drop(["prefecture","2nd_med_area", "sbp_class"], axis=1) # 120_less df_sbp_120_less = df_sbp[df_sbp.loc[:, "sbp_class"] == "120未満"].rename(columns={"40~44歳_男性": "120未満"}).drop(["prefecture","2nd_med_area", "sbp_class"], axis=1) # dfの結合 df_sbp = pd.merge(df_sbp_180_over, df_sbp_160_180, on = "2nd_med_area_code") df_sbp = pd.merge(df_sbp,df_sbp_140_160, on = "2nd_med_area_code") df_sbp = pd.merge(df_sbp,df_sbp_130_140, on = "2nd_med_area_code") df_sbp = pd.merge(df_sbp,df_sbp_120_130, on = "2nd_med_area_code") df_sbp = pd.merge(df_sbp,df_sbp_120_less, on = "2nd_med_area_code") # 列名の変更 df_sbp = df_sbp.rename(columns={"180以上": "180_over", "160以上180未満": "160_180", "140以上160未満": "140_160", "130以上140未満": "130_140", "120以上130未満": "120_130", "120未満": "120_less" }) # エクセルファイルに出力 df_sbp.to_excel("SBP_2ndmed_7ndb_40_44_m.xlsx") 〜
以上のコードを行うと、以下のように元のエクセルファイルを整形することができます。 個人的にはこちらのほうが解析しやすいので、今後機械学習などの説明変数として利用する際に利用していきたいと思います。
参考サイト
第7回NDBオープンデータ https://www.mhlw.go.jp/stf/seisakunitsuite/bunya/0000177221_00011.html