Home 의약품 처방정보 분석
Post
Cancel

의약품 처방정보 분석

의약품 처방정보

1. 소개

공공 데이터 포털에서 제공하는 의약품 처방 정보를 이용해 분석과 EDA를 진행해본 프로젝트

2. 목표

  • EDA와 시각화
  • 대용량 데이터 다뤄보기

3. 데이터 셋

공공 데이터 포털에서 제공하는 의약품 처방 정보

4. 구현

라이브러리

1
2
3
4
import numpy as np
import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt

한글 폰트 설정

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
# 데이터 시각화 도구에서 한글을 그대로 출력하게 되면 글자가 깨져서 나오게 되기 때문에 글꼴설정을 합니다.
def get_font_family():
    """
    시스템 환경에 따른 기본 폰트명을 반환하는 함수
    """
    import platform
    system_name = platform.system()
    # colab 사용자는 system_name이 'Linux'로 확인

    if system_name == "Darwin" :
        font_family = "AppleGothic"
    elif system_name == "Windows":
        font_family = "Malgun Gothic"
    else:
        # Linux
        !apt-get install fonts-nanum -qq  > /dev/null
        !fc-cache -fv

        import matplotlib as mpl
        mpl.font_manager._rebuild()
        findfont = mpl.font_manager.fontManager.findfont
        mpl.font_manager.findfont = findfont
        mpl.backends.backend_agg.findfont = findfont
        
        font_family = "NanumBarunGothic"
    return font_family

# 위에서 만든 함수를 통해 시스템 폰트를 불러옵니다.
get_font_family()

# 시각화를 위한 폰트설정
# 위에서 만든 함수를 통해 시스템 폰트를 불러와서 font_family라는 변수에 할당합니다.
import matplotlib.pyplot as plt
plt.style.use("ggplot")

font_family = get_font_family()
# 폰트설정
plt.rc("font", family=font_family)
# 마이너스 폰트 설정
plt.rc("axes", unicode_minus=False)
# 그래프에 retina display 적용
from IPython.display import set_matplotlib_formats
set_matplotlib_formats("retina")

Data Load

1
2
import glob
glob.glob("data/*")
1
2
3
['data\\HP_T60_2020_1.CSV',
 'data\\HP_T60_2020_2.CSV',
 'data\\HP_T60_2020_3.CSV']
1
2
3
df_1 = pd.read_csv("data/HP_T60_2020_1.CSV", encoding="cp949")
df_2 = pd.read_csv("data/HP_T60_2020_2.CSV", encoding="cp949")
df_3 = pd.read_csv("data/HP_T60_2020_3.CSV", encoding="cp949")
1
df_1.shape, df_2.shape, df_3.shape
1
((10994920, 15), (10952199, 15), (10923225, 15))
1
2
df = pd.concat([df_1, df_2], axis=0)
df = pd.concat([df, df_3], axis=0)
1
df.shape
1
(32870344, 15)
1
df.sample(10)
기준년도가입자 일련번호처방내역일련번호일련번호성별코드연령대코드(5세단위)시도코드요양개시일자약품일반성분명코드1회 투약량1일투약량총투여일수단가금액데이터 공개일자
5049702202014829484054803215112020-12-22152302ATR1.027190.026602021-12-29
35925752020776325112738773210112020-02-27430101ATB1.037124.026042021-12-29
1097653202070043512000010412412020-02-03150045ASY4.03334.012242021-12-29
28508402020523194326042113412020-01-02246501ATB1.033090.081002021-12-29
10898383202066502311376272227462020-07-01614901ATB1.027152.021282021-12-29
580118020208726228807302213272020-04-14453902ATB1.024148.011842021-12-29
120571820203699104583863211442020-11-04222901ATB1.035103.015452021-12-29
762342202035641816972853212452020-01-10470901ATB1.0184553.0464522021-12-29
351595202034389311577673526262020-10-08454001ATB1.0198610.0597802021-12-29
7960139202057565655370741213482020-08-31157201ATB1.0343847.0461642021-12-29

데이터 요약

1
df.info()
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<class 'pandas.core.frame.DataFrame'>
Int64Index: 32870344 entries, 0 to 10923224
Data columns (total 15 columns):
 #   Column       Dtype  
---  ------       -----  
 0   기준년도         int64  
 1   가입자 일련번호     int64  
 2   처방내역일련번호     int64  
 3   일련번호         int64  
 4   성별코드         int64  
 5   연령대코드(5세단위)  int64  
 6   시도코드         int64  
 7   요양개시일자       object 
 8   약품일반성분명코드    object 
 9   1회 투약량       float64
 10  1일투약량        int64  
 11  총투여일수        int64  
 12  단가           float64
 13  금액           int64  
 14  데이터 공개일자     object 
dtypes: float64(2), int64(10), object(3)
memory usage: 3.9+ GB
1
df.nunique()
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
기준년도                 1
가입자 일련번호       1000000
처방내역일련번호       8746682
일련번호                72
성별코드                 2
연령대코드(5세단위)         18
시도코드                17
요양개시일자             366
약품일반성분명코드         3024
1회 투약량            1158
1일투약량               33
총투여일수              328
단가                2727
금액               53976
데이터 공개일자             1
dtype: int64
1
2
3
# 한 번 처방 받을 때 받는 약의 갯수
plt.xlim(0,20)
_ = df["처방내역일련번호"].value_counts().hist(bins=30)

png

전처리

1
df.isna().sum()
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
기준년도              0
가입자 일련번호          0
처방내역일련번호          0
일련번호              0
성별코드              0
연령대코드(5세단위)       0
시도코드              0
요양개시일자            0
약품일반성분명코드      2467
1회 투약량            0
1일투약량             0
총투여일수             0
단가                0
금액                0
데이터 공개일자          0
dtype: int64

결측치 처리

1
df = df.dropna()

사용하지 않는 데이터 제거

1
2
del df["데이터 공개일자"]
df.head()
기준년도가입자 일련번호처방내역일련번호일련번호성별코드연령대코드(5세단위)시도코드요양개시일자약품일반성분명코드1회 투약량1일투약량총투여일수단가금액
02020370117885231213412020-10-16222901ATB1.033103.0927
1202046697947401213412020-06-05222901ATB1.033103.0927
220205385620454129412020-11-28222901ATB1.033103.0927
320204502102435871214412020-03-24222901ATB1.033103.0927
42020450210976991214412020-10-31222901ATB1.033103.0927

데이터 타입 변경

1
df["요양개시일자"] = pd.to_datetime(df["요양개시일자"])
1
df.info()
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<class 'pandas.core.frame.DataFrame'>
Int64Index: 32867877 entries, 0 to 10923224
Data columns (total 14 columns):
 #   Column       Dtype         
---  ------       -----         
 0   기준년도         int64         
 1   가입자 일련번호     int64         
 2   처방내역일련번호     int64         
 3   일련번호         int64         
 4   성별코드         int64         
 5   연령대코드(5세단위)  int64         
 6   시도코드         int64         
 7   요양개시일자       datetime64[ns]
 8   약품일반성분명코드    object        
 9   1회 투약량       float64       
 10  1일투약량        int64         
 11  총투여일수        int64         
 12  단가           float64       
 13  금액           int64         
dtypes: datetime64[ns](1), float64(2), int64(10), object(1)
memory usage: 3.7+ GB

파생변수 (월, 일, 요일)

1
2
3
4
df[''] = df['요양개시일자'].dt.month
df[''] = df['요양개시일자'].dt.day
df['요일'] = df['요양개시일자'].dt.dayofweek
df['영문요일'] = df["요양개시일자"].dt.day_name()
1
df.head()
기준년도가입자 일련번호처방내역일련번호일련번호성별코드연령대코드(5세단위)시도코드요양개시일자약품일반성분명코드1회 투약량1일투약량총투여일수단가금액요일영문요일
02020370117885231213412020-10-16222901ATB1.033103.092710164Friday
1202046697947401213412020-06-05222901ATB1.033103.0927654Friday
220205385620454129412020-11-28222901ATB1.033103.092711285Saturday
320204502102435871214412020-03-24222901ATB1.033103.09273241Tuesday
42020450210976991214412020-10-31222901ATB1.033103.092710315Saturday

파생변수 (시도명)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
city = """11 서울특별시
42 강원도
26 부산광역시
43 충청북도
27 대구광역시
44 충청남도
28 인천광역시
45 전라북도
29 광주광역시
46 전라남도
30 대전광역시
47 경상북도
31 울산광역시
48 경상남도
36 세종특별자치시
49 제주특별자치도
41 경기도"""
city
1
'11 서울특별시\n42 강원도\n26 부산광역시\n43 충청북도\n27 대구광역시\n44 충청남도\n28 인천광역시\n45 전라북도\n29 광주광역시\n46 전라남도\n30 대전광역시\n47 경상북도\n31 울산광역시\n48 경상남도\n36 세종특별자치시\n49 제주특별자치도\n41 경기도'
1
2
3
city_list = city.split("\n")
city_name = {c.split()[0] : c.split()[1] for c in city_list}
city_name
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
{'11': '서울특별시',
 '42': '강원도',
 '26': '부산광역시',
 '43': '충청북도',
 '27': '대구광역시',
 '44': '충청남도',
 '28': '인천광역시',
 '45': '전라북도',
 '29': '광주광역시',
 '46': '전라남도',
 '30': '대전광역시',
 '47': '경상북도',
 '31': '울산광역시',
 '48': '경상남도',
 '36': '세종특별자치시',
 '49': '제주특별자치도',
 '41': '경기도'}
1
df['시도명'] = df["시도코드"].astype(str).map(lambda x: city_name[x])

파생변수 (연령대)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
age_code = """1 00~04세 
2 05~09세
3 10~14세
4 15~19세
5 20~24세
6 25~29세
7 30~34세
8 35~39세
9 40~44세
10 45~49세
11 50~54세
12 55~59세
13 60~64세
14 65~69세
15 70~74세
16 75~79세
17 80~84세
18 85세+"""
age_code
1
'1 00~04세 \n2 05~09세\n3 10~14세\n4 15~19세\n5 20~24세\n6 25~29세\n7 30~34세\n8 35~39세\n9 40~44세\n10 45~49세\n11 50~54세\n12 55~59세\n13 60~64세\n14 65~69세\n15 70~74세\n16 75~79세\n17 80~84세\n18 85세+'
1
2
3
age_list = age_code.split("\n")
age_dict = {a.split()[0] : a.split()[1] for a in age_list}
age_dict
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
{'1': '00~04세',
 '2': '05~09세',
 '3': '10~14세',
 '4': '15~19세',
 '5': '20~24세',
 '6': '25~29세',
 '7': '30~34세',
 '8': '35~39세',
 '9': '40~44세',
 '10': '45~49세',
 '11': '50~54세',
 '12': '55~59세',
 '13': '60~64세',
 '14': '65~69세',
 '15': '70~74세',
 '16': '75~79세',
 '17': '80~84세',
 '18': '85세+'}
1
df["연령대"] = df["연령대코드(5세단위)"].astype(str).map(lambda x: age_dict[x])

파생변수 (성별)

1
2
gender_dict = {1 : "", 2 : ""}
df["성별"] = df["성별코드"].map(gender_dict)

파생변수 (투여경로, 제형)

1
2
3
4
5
6
7
8
9
10
# 투여 경로명, 제형명 파생변수 만들기
table = pd.read_html("https://www.health.kr/drug_info/basedrug/main_ingredient.html")
# 제형명
code, name = table[1]["제형코드"], table[1]["제형명칭"]
form = dict(zip(code, name))
# 투여 경로명
route = {"A":"내복제", "B":"주사제", "C":"외용제", "D":"기타"}

df["투여경로명"] = df["약품일반성분명코드"].str[6].map(lambda x: route[x])
df["제형명칭"] = df["약품일반성분명코드"].str[7:9].map(lambda x: form[x])
1
df.head()
기준년도가입자 일련번호처방내역일련번호일련번호성별코드연령대코드(5세단위)시도코드요양개시일자약품일반성분명코드1회 투약량...금액요일영문요일시도명연령대성별투여경로명제형명칭
02020370117885231213412020-10-16222901ATB1.0...92710164Friday경기도60~64세내복제정제, 저작정
1202046697947401213412020-06-05222901ATB1.0...927654Friday경기도60~64세내복제정제, 저작정
220205385620454129412020-11-28222901ATB1.0...92711285Saturday경기도40~44세내복제정제, 저작정
320204502102435871214412020-03-24222901ATB1.0...9273241Tuesday경기도65~69세내복제정제, 저작정
42020450210976991214412020-10-31222901ATB1.0...92710315Saturday경기도65~69세내복제정제, 저작정

5 rows × 23 columns

시각화

1
_ = df.hist(figsize=(14,12), bins=50)

png

1
2
plt.figure(figsize=(10, 10))
_ = sns.heatmap(df.corr(), annot=True, cmap="coolwarm", vmin=-1, vmax=1, mask=np.triu(np.ones_like(df.corr()))).set_title("상관 관계")

png

1
2
plt.figure(figsize=(20, 4))
_ = sns.countplot(data=df, x="").set_title("월별 처방 횟수")

png

1
2
plt.figure(figsize=(20, 4))
_ = sns.countplot(data=df, x="").set_title("일별 처방 횟수")

png

1
2
plt.figure(figsize=(20, 4))
_ = sns.countplot(data=df.sort_values("요일"), x="영문요일").set_title("요일별 처방 횟수")

png

1
2
plt.figure(figsize=(20, 4))
_ = sns.countplot(data=df.sort_values("연령대코드(5세단위)"), x="연령대").set_title("연령대별 처방")

png

1
2
plt.figure(figsize=(20, 4))
_ = sns.countplot(data=df.sort_values("연령대코드(5세단위)"), x="연령대", hue="성별").set_title("연령대별 성병 처방")

png

1
2
plt.figure(figsize=(20, 4))
_ = df.groupby("연령대")["단가"].mean().plot(kind="bar", rot=30).set_title("연령대별 평균 단가")

png

1
2
plt.figure(figsize=(20, 4))
_ = df.groupby("연령대").count().plot(kind="bar", rot=30).set_title("연령대별 빈도수")
1
<Figure size 1440x288 with 0 Axes>

png

This post is licensed under CC BY 4.0 by the author.

KOSIS 암 검진 데이터 시각화

[minimal_mistakes] 블로그 내 검색 기능 추가하기

Comments powered by Disqus.