내일배움캠프(QC,QA_5기)

[내일배움캠프_QA/QC 5기] 21일차 _ 팀 프로젝트 _ 제약 데이터 전처리

qc-standard 2026. 4. 6. 22:14

2026/04/06 Mon.

 

오전은 코드카타 문제 푸는데 대부분의 시간을 보내고

오후는 온전히 서브 프로젝트 전처리하는데 시간을 보냈다

 

코드카타,,, 뒤로 갈수록 푸는 시간이 더 많이 할애된다,,,

 

서브 프로젝트는 그냥 하루를 잡아먹는다

서브 프로젝트 전처리,,, 혼자 하면서,,,, 너무 힘들다는 생각을 많이 하게 된다


⊙ 팀 프로젝트_데이터 분석

시나리오 수립

 가설

: 계절에 따라 의약품 별 처방량이 유의미하게 변화할 것이다.

 예상 인사이트

: 계절별 의약품 처방 패턴을 분석하고 시각화 함으로써, 생산팀 및 재고관리팀이 계절별 수요 변화에 맞춰 생산량 조정 및 재고 최적화 의사결정에 활용할 수 있다.

 전처리

  • 데이터 확인 → 결측치 확인 → 결측치 제거
  • 컬럼 정리 = 필요없는 컬럼 제거
  • 요양 개시 일자
    : datetime으로 변환하여 계절 컬럼 생성에 활용
  • 총 투여량
    : 신규 컬럼
    : 약품 수요 파악을 위한 컬럼
    : 1일 투약량 * 총 투여일수
  • (도메일 지식 첨가) ATC 코드별 분류 컬럼 추가
  • 도시코드명 → 시도명 컬럼 추가

 시각화

  • 관리 의약품 코드를 리스트로 생성 → 총 투여일수 별 분포 / 총 투여량 별 분포
    분포별 확인하여 이상치=중독 의심 데이터를 찾아낸다  결측치 확인 → 결측치 제거
  • 히트맵을 사용하여 계절별 의약품 사용량을 색의 진하기로 표현
  • 막대그래프를 사용하여 계절별 의약품 카테고리 사용량 비교
  • 라인그래프 (시계열) 를 사용하여 월별 의약품 사용 추이 분석

 

 

코드 정보

더보기

연령대 코드 분류

1 : 0~4세
2 : 5~9세
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~89세
19 : 90~94세
20 : 95~99세
21 : 100세 이상'

 

 

ATC 코드 분류

 

<국제 ATC 코드 분류>

● A - 소화기관 및 대사
 B - 혈액 및 조혈기관
 C - 심혈관계
●  D - 피부과용약
●  G - 비뇨생식기계 및 성호르몬
●  H - 전신성 호르몬제
●  J - 전신성 항감염제
●  L - 항종양제 및 면역조절제
●  M - 근골격계
●  N - 신경계
●  P - 기생충 구제약
●  R - 호흡기계
●  S - 감각기관
●  V - 기타
<국내 ATC 코드 분류>
134401ATB
- 앞 4자리 : 성분 일련번호
- 5~6자리 : 함량 일련번호
- 마지막 : 제형코드
A : 내복제 (정제/캡슐)
B : 내복제(액제/시럽)
C : 주사제
D : 외용제(연고/크림)
E : 점안제/점이크림
F : 점이제
G : 점비제
H : 흡이제
I : 기타제형
J : 패치제 / 첩부제
K : 투석

 1523A - 해열/진통/소염제
 1038A - 해열/진통/소염제
 1523B - 해열/진통/소염제
 1052A - 소화성궤양용제
 1060A - 소화성궤양용제
 1933A - 혈압강하제
 4893A - 동맥경화용제
 1014A - 진해거담제
 1031A - 항히스타민제
 4806A - 고지혈증치료제
 1835A - 항정신병제
 1721A - 부신호르몬제
1163A - 항히스타민제
2209A - 위장관운동조절제
4539A - 기타의 중추신경용약
1063A - 위점막보호제
1861A - 해열/진통/소염제
2013A - 제산제
2229A - 위장관운동조절제

 

 

도시 코드 분류

11 : 서울
26 : 부산
27 : 대구
28 : 인천
29 : 광주
30 : 대전
31 : 울산
36 : 세종
41 : 경기
42 : 강원
43 : 충북
44 : 충남
45 : 전북
46 : 전남
47 : 경북
48 : 경남
49 : 제주

 

 

 

 

데이터 전처리

더보기

 


from
 google.colab import drive
drive.mount('/content/drive') # 구글 드라이브 연결

import warnings
warnings.filterwarnings('ignore') # warning 무시


import
 pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
import glob

# 한글 깨지방지
!sudo apt-get install -y fonts-nanum
!sudo fc-cache -fv
!rm ~/.cache/matplotlib -rf


#데이터 전처리
df = pd.read_csv('/content/1번파일_샘플링_1000건.csv')

#데이터 확인
df.info()

#데이터 결측치 개수 확인
df.isnull().sum()

#결측지 제거
df_clean = df.dropna(subset=['약품일반성분명코드(ATC코드)'])

#결측치 없는 데이터


#컬럼 정리
columns_keep = [
    '성별코드', '연령대코드(5세단위)', '시도코드', '요양개시일자',
    '약품일반성분명코드(ATC코드)', '1회투약량', '1일투약량', '총투여일수'
]
df_analysis = df[columns_keep].copy()
df_analysis.head()

#요양개시일 날짜데이터로 변환 후 오름차순 정렬
df_analysis['요양개시일자'] = pd.to_datetime(df_analysis['요양개시일자'])

df_analysis = df_analysis.sort_values(by='요양개시일자').reset_index(drop=True)

df_analysis.head()

#ATC 코드별
def atc_major_code(atc_str):
    if pd.isna(atc_str): return None

    for char in str(atc_str):
        if char.isalpha():
            return char.upper()
    return None

atc_major_mapping = {
    'A': '소화기관 및 대사', 'B': '혈액 및 조혈기관', 'C': '심혈관계',
    'D': '피부과용약', 'G': '비뇨생식기계 및 성호르몬', 'H': '전신성 호르몬제',
    'J': '전신성 항감염제', 'L': '항종양제 및 면역조절제', 'M': '근골격계',
    'N': '신경계', 'P': '기생충 구제약', 'R': '호흡기계',
    'S': '감각기관', 'V': '기타'
}


atc_detail_mapping = {
    '1523A': '해열/진통/소염제', '1038A': '해열/진통/소염제', '1523B': '해열/진통/소염제',
    '1052A': '소화성궤양용제', '1060A': '소화성궤양용제', '1933A': '혈압강하제',
    '4893A': '동맥경화용제', '1014A': '진해거담제', '1031A': '항히스타민제',
    '4806A': '고지혈증치료제', '1835A': '항정신병제', '1721A': '부신호르몬제'
}


df_analysis['ATC_대분류_코드'] = df_analysis['약품일반성분명코드(ATC코드)'].apply(atc_major_code)
df_analysis['약물계통_대분류'] = df_analysis['ATC_대분류_코드'].map(atc_major_mapping)
df_analysis['약물계통_세부'] = df_analysis['약품일반성분명코드(ATC코드)'].map(atc_detail_mapping).fillna('미분류/기타')


new_order = [
    '성별코드', '연령대코드(5세단위)', '시도코드', '요양개시일자',
    '약품일반성분명코드(ATC코드)', 'ATC_대분류_코드', '약물계통_대분류', '약물계통_세부',
    '1회투약량', '1일투약량', '총투여일수'
]

df_analysis = df_analysis[new_order]

df_analysis.head()


# 총 투여량 컬럼 추가

df_analysis['총 투여량'] = df_analysis['1일투약량'] * df_analysis['총투여일수']

new_order = [
    '성별코드', '연령대코드(5세단위)', '시도코드', '요양개시일자',
    '약품일반성분명코드(ATC코드)', 'ATC_대분류_코드', '약물계통_대분류', '약물계통_세부',
    '1회투약량', '1일투약량', '총투여일수', '총 투여량'
]

df_analysis = df_analysis[new_order]

df_analysis.head()


#계절별 컬럼 추가
def season(date):
    month = date.month
    if 3 <= month <= 5:
        return '봄'
    elif 6 <= month <= 8:
        return '여름'
    elif 9 <= month <= 11:
        return '가을'
    else:
        return '겨울'


df_analysis['계절'] = df_analysis['요양개시일자'].apply(season)


new_order = [
    '성별코드', '연령대코드(5세단위)', '시도코드', '요양개시일자', '계절',
    '약품일반성분명코드(ATC코드)', 'ATC_대분류_코드', '약물계통_대분류', '약물계통_세부',
    '1회투약량', '1일투약량', '총투여일수', '총 투여량'
]
df_analysis = df_analysis[new_order]


df_analysis.tail()

#도시별 컬럼 추가

sido_mapping = {
    11: '서울', 26: '부산', 27: '대구', 28: '인천', 29: '광주',
    30: '대전', 31: '울산', 36: '세종', 41: '경기', 42: '강원',
    43: '충북', 44: '충남', 45: '전북', 46: '전남', 47: '경북',
    48: '경남', 49: '제주'
}


df_analysis['시도명'] = df_analysis['시도코드'].map(sido_mapping)


new_order = [
    '성별코드', '연령대코드(5세단위)', '시도코드', '시도명', '요양개시일자', '계절',
    '약품일반성분명코드(ATC코드)', 'ATC_대분류_코드', '약물계통_대분류', '약물계통_세부',
    '1회투약량', '1일투약량', '총투여일수', '총 투여량'
]
df_analysis = df_analysis[new_order]


df_analysis.head()