Path to でーたさいえんてぃすと

データサイエンスの勉強の過程を公開していきます。

NDBオープンデータ(二次医療圏別LDLコレステロール)のクリーニング


第7回NDBオープンデータのデータクリーニングを行ったソースコードを載せます。  

今回の元データは 特定健診によって得られたデータである、LDLコレステロール 二次医療圏別製年齢階級別分布です。

元データは以下のようなエクセルファイルです。

図1 クリーニング前のデータ

データ解析しやすいように、LDLコレステロールのクラスは列に設定しました。  

下のコードの年齢と性別の部分を変えれば、自由にエクセルファイルに出力が可能です。  

例として、男性の全年齢階級合計(中計)の二次医療圏別性年齢階級LDLコレステロール分布をデータクリーニングしてみます。

import numpy as np
import pandas as pd


# LDLコレステロールのデータ読み込み


df_ldl = pd.read_excel("LDLchol_2ndmed_7ndb.xlsx")


# titleを取得
df_ldl_title = df_ldl.columns[0]


# 検査データの単位を取得
df_ldl_unit = df_ldl.iloc[0, 1]


df_ldl = pd.read_excel("LDLchol_2ndmed_7ndb.xlsx", skiprows =3)



# 列名の変更
df_ldl = df_ldl.drop(df_ldl.index[[0]])
df_ldl = df_ldl.rename(columns={"Unnamed: 0": "prefecture",
 "Unnamed: 1": "2nd_med_area_code", 
 "Unnamed: 2": "2nd_med_area",
 "Unnamed: 3": "ldl_class"
 })



# 都道府県などの欠損値を穴埋め
df_ldl = df_ldl.fillna(method="ffill")


# 二次医療圏判別不可を除外
df_ldl = df_ldl[df_ldl.loc[:, "prefecture"] != "二次医療圏判別不可"]



# 男性と女性のデータを区別


# 男性
rename_cols = ["40~44歳", "45~49歳", "50~54歳", "55~59歳", "60~64歳", "65~69歳", "70~74歳", '中計']
df_ldl = df_ldl.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_ldl = df_ldl.rename(columns={rename_col_woman: rename_col_woman.replace(".1", "") for rename_col_woman in rename_cols_women})
df_ldl = df_ldl.rename(columns={rename_col: f"{rename_col}_女性" for rename_col in rename_cols})




# 今回は男性の中計のデータを抽出
df_ldl = df_ldl.loc[:, ["prefecture","2nd_med_area_code", "2nd_med_area", "ldl_class", "中計_男性"]]




# 180overだけprefectureなどの列を残し、他のdfは血圧の列だけにして、後でmergeで結合
# 2nd_med_area_codeで結合しないと、同じ名前の二次医療圏があってdfの行数がおかしくなる



# 180_over 
df_ldl_180_over = df_ldl[df_ldl.loc[:, "ldl_class"] == "180以上"].rename(columns={"中計_男性": "180以上"}).drop("ldl_class", axis=1)


# 160-180
df_ldl_160_180 = df_ldl[df_ldl.loc[:, "ldl_class"] == "160以上180未満"].rename(columns={"中計_男性": "160以上180未満"}).drop(["prefecture","2nd_med_area", "ldl_class"], axis=1)


# 140-160
df_ldl_140_160 = df_ldl[df_ldl.loc[:, "ldl_class"] == "140以上160未満"].rename(columns={"中計_男性": "140以上160未満"}).drop(["prefecture","2nd_med_area", "ldl_class"], axis=1)


# 130-140
df_ldl_120_140 = df_ldl[df_ldl.loc[:, "ldl_class"] == "120以上140未満"].rename(columns={"中計_男性": "120以上140未満"}).drop(["prefecture","2nd_med_area", "ldl_class"], axis=1)


# 120-130
df_ldl_100_120 = df_ldl[df_ldl.loc[:, "ldl_class"] == "100以上120未満"].rename(columns={"中計_男性": "100以上120未満"}).drop(["prefecture","2nd_med_area", "ldl_class"], axis=1)


# 120_less
df_ldl_100_less = df_ldl[df_ldl.loc[:, "ldl_class"] == "100未満"].rename(columns={"中計_男性": "100未満"}).drop(["prefecture","2nd_med_area", "ldl_class"], axis=1)




# dfの結合
df_ldl = pd.merge(df_ldl_180_over, df_ldl_160_180, on = "2nd_med_area_code")
df_ldl = pd.merge(df_ldl,df_ldl_140_160, on = "2nd_med_area_code")
df_ldl = pd.merge(df_ldl,df_ldl_120_140, on = "2nd_med_area_code")
df_ldl = pd.merge(df_ldl,df_ldl_100_120, on = "2nd_med_area_code")
df_ldl = pd.merge(df_ldl,df_ldl_100_less, on = "2nd_med_area_code")



# 列名の変更
df_ldl = df_ldl.rename(columns={"180以上": "ldl_180_over",
 "160以上180未満": "ldl_160_180", 
 "140以上160未満": "ldl_140_160",
 "120以上140未満": "ldl_120_140",
 "100以上120未満": "ldl_100_120",
 "100未満": "ldl_100_less"
 })



# エクセルファイルに出力
df_ldl.to_excel("LDL_2ndmed_7ndb_total_m.xlsx")

〜

以上のコードを行うと、以下のように元のエクセルファイルを整形することができます。

図2 クリーニング後のデータ

  参考サイト

第7回NDBオープンデータ

https://www.mhlw.go.jp/stf/seisakunitsuite/bunya/0000177221_00011.html