find_hospital 함수
## tabulate library가 없는 경우 설치 필요
## pandas.to_markdown() 시 tabulate library가 필요함
!pip install tabulate
import pandas as pd
from urllib.parse import quote
from haversine import haversine
import ssl
from urllib.request import urlopen
import numpy as np
context=ssl.create_default_context()
context.set_ciphers("DEFAULT")
#########################################
# 1) 함수 선언하기 #
#########################################
# 함수명 : find_hospital
# 매개변수 : special_m (중증질환명), lati, long (환자 위치)
def find_hospital(special_m, lati, long ):
# [국립중앙의료원 - 전국응급의료기관 조회 서비스] 활용을 위한 개인 일반 인증키(Encoding) 저장
key = "키값"
# city = 대구광역시, 인코딩 필요
city = quote("대구광역시")
############################################################
# 2) 병원 리스트 csv 파일 불러오기 (daegu_hospital_list.csv) #
############################################################
solution_df = pd.read_csv('./daegu_hospital_list.csv')
############################################################
# 3) 병원 실시간 정보 가져오기 #
############################################################
# 응급실 실시간 가용병상
url_realtime = "https://apis.data.go.kr/B552657/ErmctInfoInqireService/getEmrrmRltmUsefulSckbdInfoInqire?serviceKey=" + key + "&STAGE1=" + city + "&numOfRows=100&pageNo=1"
result = urlopen(url_realtime, context=context)
emrRealtime_big = pd.read_xml(result, xpath='//item')
## 응급실 실시간 가용병상 정보에서 기관코드(hpid), 응급실 병상수('hvec'), 수술실 수('hvoc') 정보만 추출하여 emRealtime_small 변수에 저장
## emrRealtime_big 중 [hpid, hvec, hvoc] 컬럼 활용
emrRealtime_small = emrRealtime_big[['hpid', 'hvec', 'hvoc']] ## emrRealtime_big 중 [hpid, hvec, hvoc] 컬럼 활용
# solution_df와 emrRealtime_small 데이터프레임을 결합하여 solution_df에 저장
solution_df = pd.merge(solution_df, emrRealtime_small, on = 'hpid',how='inner')
# 실시간 중증질환자 수용 가능 병원 조회
url_acpt = 'https://apis.data.go.kr/B552657/ErmctInfoInqireService/getSrsillDissAceptncPosblInfoInqire?serviceKey=' + key + "&STAGE1=" +city + "&numOfRows=100&pageNo=1"
result = urlopen(url_acpt, context=context)
emrAcpt_big = pd.read_xml(result, xpath='.//item')
## 다른 API함수와 다르게 기관코드 컬럼명이 다름 (hpid --> dutyName)
## 기관코드 컬렴명을 'hpid'로 일치화시키기 위해, 컬럼명을 변경함
emrAcpt_big.rename(columns = {'dutyName' : 'hpid'}, inplace = True)
## 실시간 중증질환자 수용 가능 병원정보에서 필요한 정보만 추출하여 emrAcpt_small 변수에 저장
## emrAcpt 중 [hpid, MKioskTy1, MKioskTy2, MKioskTy3, MKioskTy4, MKioskTy5, MKioskTy7,MKioskTy8, MKioskTy10, MKioskTy11] 컬럼 확인
emrAcpt_small = emrAcpt_big[['hpid', 'MKioskTy1', 'MKioskTy2', 'MKioskTy3', 'MKioskTy4', 'MKioskTy5', 'MKioskTy7','MKioskTy8', 'MKioskTy10', 'MKioskTy11']]
# solution_df와 emrAcpt_small 데이터프레임을 결합하여 solution_df에 저장
solution_df = pd.merge(solution_df, emrAcpt_small, on = 'hpid',how = 'inner')
############################################################
# 4) 자료 정비하기 #
############################################################
# solution_df의 컬럼명 변경하기
column_change = { 'hpid' : '병원코드',
'dutyName' : '병원명',
'dutyAddr' : '주소',
'dutyTel3' : '응급연락처',
'wgs84Lat' : '위도',
'wgs84Lon' : '경도',
'hperyn' : '응급실수',
'hpopyn' : '수술실수',
'hvec' : '가용응급실수',
'hvoc' : '가용수술실수',
'MKioskTy1' : '뇌출혈',
'MKioskTy2' : '뇌경색',
'MKioskTy3' : '심근경색',
'MKioskTy4' : '복부손상',
'MKioskTy5' : '사지접합',
'MKioskTy7' : '응급투석',
'MKioskTy8' : '조산산모',
'MKioskTy10' : '신생아',
'MKioskTy11' : '중증화상',
}
solution_df = solution_df.rename(columns = column_change)
# 중증질환 수용 가능 여부 데이터 중 정보 미제공, 불가능은 N로 변경 : replace
solution_df = solution_df.replace("정보미제공","N")
solution_df = solution_df.replace("불가능","N")
## 응급실수/가용응급실수, 수술실수/가용수술실 수가 0보다 작은 경우는 비정상 데이터로 추정
## 0보다 작은 수는 0으로 변경
solution_df.loc[solution_df['응급실수']<0, '응급실수'] = 0
solution_df.loc[solution_df['수술실수']<0, '수술실수'] = 0
solution_df.loc[solution_df['가용응급실수']<0, '가용응급실수'] = 0
solution_df.loc[solution_df['가용수술실수']<0, '가용수술실수'] = 0
# 응급실 가용율을 구하여 새로운 컬럼으로 추가하기
# 컬렴명 : '응급실가용율'
# 산식 : 가용 응급실수 / 응급실 수
# 소수 둘째 자리까지 구하기 round() 활용
solution_df['응급실가용율'] = round(solution_df['가용응급실수'] / solution_df['응급실수'], 2)
# 응급실 가용율이 1이 넘는 경우는 1로 대체
solution_df.loc[solution_df['응급실가용율'] > 1, '응급실가용율'] = 1
# 응급실 가용율에 따라 포화도 분류
# 응급실 가용율 구분 단계 : ~0.1, 0.1 ~ 0.3, 0.3 ~ 0.6, 0.6 ~
# 포화도 명칭 : ['불가', '혼잡', '보통', '원활']
# pd.cut() 활용
bins = [-np.inf, 0.1, 0.3, 0.6, np.inf]
labels = ['불가', '혼잡', '보통', '원활']
solution_df['응급실포화도'] = pd.cut(solution_df['응급실가용율'], bins=bins, labels=labels)
############################################################
# 5) 환자 수용 가능한 병원 구하기 #
############################################################
# 매개변수 special_m로 받은 중증질환이 중증질환 리스트에 포함될 경우
# 중증질환 리스트 : ['뇌출혈', '뇌경색', '심근경색', '복부손상', '사지접합', '응급투석', '조산산모', '신생아','중증화상' ]
severe_diseases = ['뇌출혈', '뇌경색', '심근경색', '복부손상', '사지접합', '응급투석', '조산산모', '신생아','중증화상']
if special_m in severe_diseases:
# 조건1 : special_m 중증질환자 수용이 가능하고
# 조건2 : 응급실 포화도가 불가가 아닌 병원
condition1 = (solution_df[special_m] == 'Y') & (solution_df['가용수술실수']>=1)
condition2 = (solution_df['응급실포화도'] != '불가')
# 조건1, 2에 해당되는 응급의료기관 정보를 distance_df에 저장하기
distance_df = solution_df[condition1 & condition2].copy()
# 매개변수 special_m 값이 중증질환 리스트에 포함이 안되는 경우
else:
# 조건1 : 응급실 포화도가 불가가 아닌 병원
condition1 = solution_df['응급실포화도'] != '불가'
# 조건1에 해당되는 응급의료기관 정보를 distance_df에 저장하기
distance_df = solution_df[condition1].copy()
############################################################
# 6) 환자와 병원간 거리 구하기 #
############################################################
distance = []
patient = (lati, long)
for idx, row in distance_df.iterrows():
distance.append(round( haversine(patient,(row['위도'], row['경도']), unit='km') , 2))
distance_df.loc[:,'거리'] = distance.copy()
############################################################
# 7) 거리 구간 구하기 #
############################################################
bins = [-np.inf, 2, 5, 10, np.inf]
labels = ['2km이내', '5km이내', '10km이내', '10km이상']
distance_df.loc[:, '거리구분'] = pd.cut(distance_df['거리'], bins=bins, labels=labels)
############################################################
# 8) 결과값 반환하기 #
############################################################
return distance_df
# 중증환자 수용 가능한, 가까운 병원 조회 #1
# 환자 정보
# - 중증 질환 : 응급투석
# - 환자 위치 : 대구역 근처 (35.8765167, 128.5972922))
# 거리순, 응급실 포화도 순으로 결과 출력하기 (pandas의 sort_values(), to_markdown() 활용)
print(find_hospital('응급투석', 35.8765167, 128.5972922).sort_values(['거리구분', '응급실포화도','거리'], ascending=[True, False, True]).to_markdown())
네이버 지도 API 사용을 위한 헤더 정보
import requests
from urllib.parse import quote
# 네이버 지도 API 사용을 위한 헤더 정보
headers = {
'X-NCP-APIGW-API-KEY-ID': '키',
'X-NCP-APIGW-API-KEY': '키'
}
# 특정 위치 검색 (예: 서문시장)
def get_lat_lng(location):
url = f"https://naveropenapi.apigw.ntruss.com/map-geocode/v2/geocode?query={quote(location)}"
response = requests.get(url, headers=headers)
print(response.text)
if response.status_code == 200:
data = response.json()
if 'addresses' in data and len(data['addresses']) > 0:
lat = data['addresses'][0]['y']
lng = data['addresses'][0]['x']
return (float(lat), float(lng))
return None
# 예제
location_name = "서울특별시 중구 명동길"
patient = get_lat_lng(location_name)
print(patient)
'Aivle School 미니 프로젝트 > 5차 미니프로젝트' 카테고리의 다른 글
5차_미니프로젝트] 응급의료기관별 중증질환자 수용 가능 여부 조회 (0) | 2023.11.17 |
---|---|
5차_미니프로젝트] 응급의료기관별 기본정보 조회 - 응급실 숫자, 수술실 숫자 조회 (0) | 2023.11.17 |
5차_미니프로젝트] 대구광역시 응급의료기관 목록정보 조회 (0) | 2023.11.17 |
5차_미니프로젝트] 공공데이터 (0) | 2023.11.17 |
5차_미니프로젝트] 함수 get_location, get_optimal_route, (0) | 2023.11.17 |