일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- 파이썬 머신러닝 완벽가이드
- SQL
- MySQL
- 파이썬 철저 입문
- 내일배움캠프
- 미세먼지
- TiL
- hackerrank
- R
- 스파르타코딩
- 스파르타 코딩
- 파이썬 철저입문
- 어쩌다 마케팅
- 오블완
- Cluster
- 내일배움
- 회귀분석
- 웹 스크랩핑
- harkerrank
- 실전 데이터 분석 프로젝트
- 중회귀모형
- 파이썬 머신러닝 완벽 가이드
- 텍스트 분석
- 스파르타
- wil
- 파이썬
- 프로그래머스
- 내일배움카드
- 티스토리챌린지
- 프로젝트
- Today
- Total
OkBublewrap
API(3) 본문
https://www.data.go.kr/tcs/dss/selectApiDataDetailView.do?publicDataPk=15073861
한국환경공단_에어코리아_대기오염정보
각 측정소별 대기오염정보를 조회하기 위한 서비스로 기간별, 시도별 대기오염 정보와 통합대기환경지수 나쁨 이상 측정소 내역, 대기질(미세먼지/오존) 예보 통보 내역 등을 조회할 수 있다.
www.data.go.kr
위 api를 들고 와봤다. 정보를 찾으면서 구동은 되는데 남들 쓰는 게 다양해서 조금 시간이 걸렸다.
import requests
encoding = ''
decoding = ''
url = 'http://apis.data.go.kr/B552584/ArpltnInforInqireSvc/getCtprvnRltmMesureDnsty'
Params = {
'sidoName' : '부산',
'pageNo' : '1',
'numOfRows' : '100',
'returnType' : 'XML',
'serviceKey' : encoding,
'ver' : '1.0'
}
response = requests.get(url, params = Params)
response.content
response.content로 진행을 했을 때 한글이 깨져서 나온다. 한글로 변형하기 위해서 인코딩을 변경을 해준다.
response_encoding = str(response.content, 'utf-8')
response_encoding
<?xml version="1.0" encoding="UTF-8"?>\r\n<response>\n <header>\n <resultCode>00</resultCode>\n <resultMsg>NORMAL_CODE</resultMsg>\n </header>\n <body>\n <items>\n <item>\n <so2Grade>1</so2Grade>\n <coFlag/>\n <khaiValue>72</khaiValue>\n <so2Value>0.003</so2Value>\n <coValue>0.4</coValue>\n <pm25Flag/>\n <pm10Flag/>\n <o3Grade>2</o3Grade>\n <pm10Value>50</pm10Value>\n <khaiGrade>2</khaiGrade>\n <pm25Value>18</pm25Value>\n <sidoName>부산</sidoName>\n <no2Flag/>\n <no2Grade>1</no2Grade>\n <o3Flag/>\n <pm25Grade>2</pm25Grade>\n <so2Flag/>\n...
보기 좋게 변형 Dict
import xmltodict
dict_data = xmltodict.parse(response_encoding, xml_attribs=True)
dict_data
우선 관측대가 있는 곳을 확인을 하기 위해서 sidoname만 추출해서 보기로했다.
len(dict_data['response']['body']['items']['item'])
35개 나왔다. 부산에는 총 35개의 관측소가 있다
for i in range(35):
print(dict_data['response']['body']['items']['item'][i]['stationName'])
광복동
초량동
태종대
청학동
전포동
온천동
명장동
대연동
용호동
학장동
덕천동
화명동
삼락동
개금동
당리동
부산항
부산신항
부산북항
부산감만
청룡동
좌동
재송동
장림동
대저동
녹산동
명지동
연산동
기장읍
용수리
수정동
부곡동
회동동
광안동
대신동
덕포동
데이터 프레임 만들기
stationName을 인덱스로 넣고 행에는 여러가지변수중 종합적인 지수, 수치만 들고 오기로 했다.
우선 첫번째에 있는 광복동에 있는 수치를 들고오면 다음과 같다.
dict_data['response']['body']['items']['item']['khaiValue']
# 72
dict_data['response']['body']['items']['item'][0]['khaiGrade']
# 2
KhaiGrade는 등급은 이렇게 사용이 된다. 광북동은 보통이다.
등급 | 좋음 | 보통 | 나쁨 | 매우나쁨 |
Grade 값 | 1 | 2 | 3 | 4 |
# index
index = []
for i in range(35):
index.append(dict_data['response']['body']['items']['item'][i]['stationName'])
khaiValue = []
for i in range(35):
khaiValue.append(dict_data['response']['body']['items']['item'][i]['khaiValue'])
khaiGrade = []
for i in range(35):
khaiGrade.append(dict_data['response']['body']['items']['item'][i]['khaiGrade'])
# DataFrame
import pandas as pd
df_khai = pd.DataFrame({
'khaiValue' : khaiValue,
'khaiGrade' : khaiGrade
}, index = index
)
df_khai.head(10)
df_khai.tail(10)
다 지수들은 보통으로 나왔다. 위치상 크게 다르지 않아서 그런 것 같다.
부산항이 khaiValue : -, khaiGrade는 None으로 나왔다. 오류거나 장비 점검중인 것 같다.
# 부산에서 높은 값
df_khai.sort_values('khaiValue').tail(5)
# 부산에서 낮은 값
df_khai.sort_values('khaiValue').head(5)
khaiValue가 20이상 차이가 난 것을 볼 수 가있는데 위치를 보기 위해서 저번에 사용했던 folium을 사용해서 지도에서 표시를 할 것 이다. 우선 지도에 표기하기 위해서는 위도, 경도로 변환을 시켜 줘야 한다. 검색을 해보니 geo코딩을 통해서 좌표를 변환 시킬 수가 있었다. 우선 중심점을 표기하기 위해서 구글에서 검색한 좌표
from geopy.geocoders import Nominatim
def geocoding(address):
geolocoder = Nominatim(user_agent = 'South Korea', timeout=None)
geo = geolocoder.geocode(address)
crd = {"lat": str(geo.latitude), "lng": str(geo.longitude)}
return crd
crd = geocoding("부산 전포동")
print(crd['lat'])
print(crd['lng'])
부산 전포동을 위도, 경도 표시
35.1572828
129.0745022
위도 값 따로 경도값 따로 모아서 출력을 진행을 해야한다.
lat = []
lng = []
for i in range(35):
station_name = "부산 " + index[i]
crd = geocoding(station_name)
#lat.append(crd['lat'])
#lng.append(crd['lng'])
코드를 작성을 하는 도중 오류가 발생이 됬다. 주소명이 위도, 경도를 못찾은 경우에 이 오류가 발생한다고 한다. 주소를 가져오지 못하는 주소는 오류로 처리를 해서 넘어가게 코드를 작성을 했다.
lat = []
lng = []
for i in range(35):
try:
station_name = "부산 " + index[i]
crd = geocoding(station_name)
lat.append(crd['lat'])
lng.append(crd['lng'])
except:
pass
len(lat)을 해서 보니 3개 정도 주소를 받지 못한 것 같다. 이러면 인덱스가 문제다. 어떤게 오류가 났는지 확인할 필요가 있어 보인다.
lat = []
lng = []
for i in range(35):
try:
station_name = "부산 " + index[i]
crd = geocoding(station_name)
lat.append(crd['lat'])
lng.append(crd['lng'])
except Exception as e:
print(station_name,e)
부산 부산북항 'NoneType' object has no attribute 'latitude'
부산 부산감만 'NoneType' object has no attribute 'latitude'
부산 대신동 'NoneType' object has no attribute 'latitude'
부산 부산북항, 감만, 대신동이 위도, 경도 변환이 안 된 것을 볼 수 가 있다. 이 부분을 제외를 하고 진행을 한다.
# Index 수정
remove_set = {'부산북항', '부산감만','대신동'}
rm_index = [i for i in index if i not in remove_set]
print(rm_index)
['광복동', '초량동', '태종대', '청학동', '전포동', '온천동', '명장동', '대연동', '용호동', '학장동', '덕천동', '화명동', '삼락동', '개금동', '당리동', '부산항', '부산신항', '청룡동', '좌동', '재송동', '장림동', '대저동', '녹산동', '명지동', '연산동', '기장읍', '용수리', '수정동', '부곡동', '회동동', '광안동', '덕포동']
### 전체 코드 ###
# Package
from geopy.geocoders import Nominatim
import folium
# 위도, 경도 변환
def geocoding(address):
geolocoder = Nominatim(user_agent = 'South Korea', timeout=None)
geo = geolocoder.geocode(address)
crd = {"lat": str(geo.latitude), "lng": str(geo.longitude)}
return crd
# 각 index에 대한 위도, 경도 가져오기, 없는 값은 제외
lat = []
lng = []
for i in range(35):
try:
station_name = "부산 " + index[i]
crd = geocoding(station_name)
lat.append(crd['lat'])
lng.append(crd['lng'])
except:
pass
# 위치 중 변환 안된 Index 제외
remove_set = {'부산북항', '부산감만','대신동'}
rm_index = [i for i in index if i not in remove_set]
print(rm_index)
# 위치 표시
# 중심지점
busan_map = folium.Map(location=[35.1795543,129.0756416] zoom_start=18)
df_cities = pd.DataFrame({'위도': lat, '경도': lng},
index = rm_index)
print(df_cities)
for i in range(len(df_cities)):
folium.Marker([df_cities.iloc[i][0], df_cities.iloc[i][1]], popup=df_cities.index[i]).add_to(busan_map)
busan_map.save('busan_obs.html')
위도 경도
광복동 35.100358850000006 129.0306070630278
초량동 35.1157823 129.04265
태종대 35.05850995 129.0876858033858
청학동 35.09106 129.06497
전포동 35.1572828 129.0745022
온천동 35.2158722 129.07023
명장동 35.20755 129.10356
대연동 35.1343823 129.0938404
용호동 35.1190255 129.1126529
학장동 35.1422194 128.9843177
덕천동 35.2122143 129.0115542
화명동 35.2326638 129.010709
삼락동 35.1837761 128.9791895
개금동 35.1527311 129.0213975
당리동 35.1071561 128.9768898
부산항 35.1050889 129.0639918
부산신항 35.1178873 128.8467054
청룡동 35.28324 129.07324
좌동 35.1781799 129.1759973
재송동 35.1858554 129.124651
장림동 35.07509 128.96829
대저동 35.1586386 128.9535924
녹산동 35.1116974 128.869001
명지동 35.1071356 128.9179423
연산동 35.1834421 129.0899339
기장읍 35.2385796 129.2158159
용수리 35.33662 129.17312
수정동 35.1305163 129.0413108
부곡동 35.2339453 129.093848
회동동 35.23105 129.12173
광안동 35.1590134 129.113064
덕포동 35.1754906 128.9854608
부산신항, 부산감만을 제외한 곳에서 녹산동이 제일 높았는데 산업단지 주변이라 그런것 같다. 미세먼지 프로젝트를 했을 때 한강 기준으로 동, 서 차이가 났는데 여기서는 좌동도 높게 나온것을 보면 딱히 그렇게 의미있는 결과였던 것은 아니였던 것 같다.