오늘의 교육과정은 데이터 수집이다.
이전까지는 로컬에서 기존파일을 읽거나 Github에서 데이터를 읽어와서 데이터를 다루고 다듬고 분석했던 수업들이었다.
예를 들어 로컬에서 읽어온다면,
# 라이브러리 불러오기 import pandas as pd # 데이터 읽어오기 temp = pd.read_csv('로컬파일명.csv') # 확인 temp.head() |
Github에서 읽어온다면,
# 라이브러리 불러오기 import pandas as pd # 데이터 읽어오기 path = 'https://raw.githubusercontent.com/Gitjub주소.csv' temp = pd.read_csv(path) # 확인 temp.head() |
~ 이런 식이었다.
하지만, 로컬에서 읽는 건 필요한 데이터를 꼭 다운로드해야 하고, 시간이 지나면 과거 데이터가 되면서 최신 데이터를 다시 다운로드받아야 하는 번거로움이 있으며, 데이터를 남들과 공유할 수 없다는 단점이 있다.
Github는 자료가 변경되면 불러온 쥬피터에서 새로 실행했을 때 변경된 자료가 반영된다는 점이 장점이지만, 누군가는 Github관리 기술을 가지고 꾸준히 관리해야 한다는 단점이 있고 처음 자료공유를 위해서 업로드해야 하는 번거로움이 있다. 이 또한 로컬과 마찬가지로 시간이 지나면 서서히 과거 데이터가 된다.
우리가 필요한 데이터를 다운로드 하지 않으면서 남들과 같은 최신데이터를 실시간으로 볼 수는 없을까?
오늘 배운 오픈 API가 그 해답이다.
> 오픈 API란?
(↔ 프라이빗 Private API)
공개 API라고도 불리는 오픈(Open) API 는 개발자라면 누구나 사용할 수 있도록 공개된 API를 말하며, 개발자에게 사유 응용 소프트웨어나 웹 서비스의 프로그래밍적인 권한을 제공한다.
네이버 지식백과에서도 설명하듯이 네이버지도, 구글맵, 오픈스트리트맵 등이 대표적인 예라고 하며, 메타블로그도 그 예시라고 한다. 최근에 코로나 질병으로 인해 네이버클라우드플랫폼의 API지원을 받아 라이브코로나, 코로나 맵 등의 서비스가 생겼다고도 설명하셨다.
> 국내 주요 오픈 API사이트
를 강조해서 알려주셨다. 추후 우리에게 도움이 많이 될 사이트들이라며 강조하셨다.
아래 아이콘을 누르면 해당 사이트로 바로 이동한다.
● 공고데이터포털(추천)
● 서울 열린데이터 광장(추천)
● 문화데이터 광장
● 공간정보 오픈플랫폼
> response ( JSON & XML )
- JSON(JavaScript Object Notation) → 딕셔너리형태 { } → 데이터프레임 → 분석
데이터를 전송, 저장할 때 많이 쓰는 경량의 DATA 교환방식.
- XML(extensible markup language) → <key> value 형태
인터넷 웹페이지를 만드는 HTML을 획기적으로 개선하여 만든 언어이다.
키, 벨류형태는 동일하기 때문에 두 언어가 호환이 가능하다는 것을 강조하셨다.
>> 오픈 API 사용 방법
우선 가장 힘들었던 회원가입 먼저! (여기서 시간이 가장 많이 걸림..ㅋㅋㅋㅋ왜일까.. 의문ㅋㅋㅋㅋ)
↓
인증키 발급 (공공데이터를 사용한다면 인증키가 중요하다.)
↓
> 서울 열린데이터광장
> 지하철호선별 역별 승하차 인원 정보
# 라이브러리 불러오기 import urllib. request import json import pandas as pd |
# 인증키와 주소 key = '여기에 발급된 인증키 넣기' start = 1 end = 1000 url = f'http://openapi.seoul.go.kr:8088/{key}/json/CardSubwayStatsNew/{start}/{end}/20230211' # f스트링 사용 # 데이터 가져오기 response = urllib.request.urlopen(url) json_str = response.read().decode('utf-8') # JSON으로 변환(딕셔너리로 변환) json_object = json.loads(json_str) # 데이터프레임으로 변환 subway = pd.json_normalize(json_object['CardSubwayStatsNew']['row']) └ JSON 데이터에서 파싱하여 내가 필요한 행을 데이터프레임으로 선언해준 것. 파싱: 내가 필요한 행을 추출한다는 뜻. https://jsonformatter.org/json-parser # 확인 subway.head() |
# 데이터 분석(간단한 전처리와 분석을 하고, 시각화를 할 것) # 시각화를 위한 라이브러리 불러오기 import matplotlib.pyplot as plt # 한글폰트 지정(맑은 고딕) plt.rcParams['font.family'] = 'Malgun Gothic' |
# 열 정보 subway.info() |
# 기초통계정보 subway.describe().T |
# 승차 인원이 가장 많은 역 TOP 10을 추출하여 subway_top 10 데이터프레임을 만들기 subway_top10 = subway.sort_values(by = 'RIDE_PASGR_NUM', ascending = False).head(10) # 오름차순 ascending (값이 작은 쪽에서부터 큰 쪽으로의 순서) = False 아니다 |
# 정렬 결과로 어긋난 순서의 인덱스를 깔끔하게 초기화 subway_top10.reset_index(drop=True,inplace=True) |
# 호선별 승하차 인원 합계를 subway_linesum 데이터프레임으로 만들기 subway_linesum = subway.groupby('LINE_NUM', as_index=False)[['RIDE_PASGR_NUM','ALIGHT_PASGR_NUM']].sum() |
# 승차인원 기준으로 내림차순 정렬 subway_linesum = subway_linesum.sort_values(by='RIDE_PASGR_NUM',ascending =False) |
# 막대그래프( 계속 손으로 치는 게 답이다! 복사 붙여넣기는 머리에 남는 게 없다!) plt.figure(figsize = (10,5)) ┌ (호선) 표시 ex) 홍대입구(2호선) plt.bar(x = subway_top10['SUB_STA_NM'] + '(' + subway_top10['LINE_NUM'] + ')', height=subway_top10['RIDE_PASGR_NUM'], data=subway_top10) plt.xticks(rotation = 45) # x축 이름 다 보이게 기울기 정도 plt.show() |
> 실습 1. 서울특별시 공공자전거 실시간 대여 정보를 가져오기 #1
- 호출시 시스템 부하로 한번에 최대 1,000건을 초과할수 없다.
- 우선 1,000개 행만 조회하세요.
# 라이브러리 불러오기 import urllib. request import json import pandas as pd |
# 인증키와 주소 key = 'blablabla' start = 1 end = 1000 url = f'http://openapi.seoul.go.kr:8088/{key}/json/bikeList/{start}/{end}/' # 데이터 가져오기 response = urllib.request.urlopen(url) json_str = response.read().decode('utf-8') # JSON으로 변환(딕셔너리로 변환) json_object = json.loads(json_str) # 데이터프레임으로 변환 bike = pd.json_normalize(json_object['rentBikeStatus']['row']) └ JSON 데이터에서 파싱하여 내가 필요한 행을 데이터프레임으로 선언해준 것. 파싱: 내가 필요한 행을 추출한다는 뜻. https://jsonformatter.org/json-parser # 상위 데이터 확인 bike.head() |
> 실습 2. 서울특별시 공공자전거 실시간 대여 정보를 가져오기 #2
- 호출시 시스템 부하로 한번에 최대 1,000건을 초과할수 없다.
- 1,000건이 넘는 데이터를 한꺼번에 가져오자.
- while문을 사용하여 JSON문자열을 연결한 후 이후 과정을 진행한다.
# 강사님께서 푼 방법 # 인증키 key = '어찌구저찌구' loop = 0 result = [] # 반복해서 가져와 연결하기 while True: start = 1 +1000 * loop # 1 1001 2001~~~~n end = 1000 + 1000 *loop # start + 999해도 됨. # 1000 2000 3000~~~~n url = f'http://openapi.seoul.go.kr:8088/{key}/json/bikeList/{start}/{end}/' # 데이터 가져오기 response = urllib.request.urlopen(url) json_str = response.read().decode('utf-8') # JSON으로 변환(딕셔너리로 변환) json_object = json.loads(json_str) result += json_object['rentBikeStatus']['row'] # 탈출조건??? if len(result) % 1000 != 0: break loop += 1 # 데이터프레임으로 변환 bike = pd.json_normalize(result) # 상위 데이터 확인 bike.head() |
# 또 다른 방법 # 인증키와 주소 loop = 0 result = [] key = '12345678910' start = 1 end = 1000 # 반복해서 가져와 연결하기 while True: start = 1+ loop*1000 end = (loop+1)*1000 url = f'http://openapi.seoul.go.kr:8088/{key}/json/bikeList/{start}/{end}/' # 데이터 가져오기 response = urllib.request.urlopen(url) json_str = response.read().decode('utf-8') # JSON으로 변환 json_object = json.loads(json_str) try: result += json_object['rentBikeStatus']['row'] loop += 1 except: break # 데이터프레임으로 변환 bikes = pd.DataFrame(result) # 확인 bikes.describe() |
> 실습 3. 데이터 탐색 및 전처리
# 열 정보 bike.info() |
|
# 데이터 형식 변경 #1 bike['rackTotCnt']= bike['rackTotCnt'].astype('int') bike['parkingBikeTotCnt'] = bike['parkingBikeTotCnt'].astype('int') bike['shared']= bike['shared'].astype('int') |
# 데이터 형식 변경 #2 cols = ['rackTotCnt', 'parkingBikeTotCnt', 'shared'] bike[cols]=bike[cols].astype('int') |
# 데이터 형식 변경 #3 for col in cols: bike[col] = bike[col].astype('int') |
> 참고 : 지도 시각화
위도와 경도 정보가 있으므로 지도상에 거치대 위치를 표시할 수 있다.
# 지도 시각화를 위한 folium 라이브러리 불러오기 !pip install folium |
# 라이브러리 불러오기 import folium # 위 분석에서 거치대가 가장 많은 곳의 좌표를 지도상에 표시 m = folium.Map(location=['37.56133652','126.83390045'], tiles='openstreetmap', zoom_start=17) # 마커 표시 marker1 = folium.Marker(['37.56133652','126.83390045'], popup='LG유플러스 마곡사옥', icon=folium.Icon(color='red')) marker1.add_to(m) # 확인 m # 위 진한 부분이 비어져있었음. |
> 공공 데이터 포털
# XML을 딕셔너리 형태로 변환하는 라이브러리 불러오기 # xmltodict 패키지 설치(아나콘다에는 이미 설치 됨) !pip install xmltodict |
> 관세청_국가별 수출입실적(GW)
# 라이브러리 불러오기 import urllib.request import json import pandas as pd import xmltodict # 미리보기주소 # https://apis.data.go.kr/1220000/nationtrade/getNationtradeList?serviceKey=인증키&strtYymm=202201&endYymm=202212&cntyCd=US' # 매개변수 key = ' 일반 인증키 Encoding ' strtYymm = 202201 endYymm = 202212 cntyCd = ' ' # 주소 url = f'http://apis.data.go.kr/1220000/nationtrade/getNationtradeList?serviceKey={key}&strtYymm={strtYymm}&endYymm={endYymm}&cntyCd={cntyCd}' # 데이터 가져오기 response = urllib.request.urlopen(url) # xml --> dict xml_parse = xmltodict.parse(response) xml_dict = json.loads(json.dumps(xml_parse)) result = xml_dict['response']['body']['items']['item'] # 데이터 부분 딕셔너리 키 확인 필요 # 데이터프레임으로 변환 im_export = pd.json_normalize(result) # 확인 im_export |
|
# 소수점 네 자리까지표시 pd.set_option('display.float_format', lambda x: '%.4f' % x) |
|
# 데이터 형식 변환 cols = ['balPayments', 'expCnt', 'expDlr', 'impCnt', 'impDlr'] im_export[cols] = im_export[cols].astype('int64') |
|
# 내가 출력한 답 # 2022년 12월 무역수지 TOP 10 # im_export12 = im_export.loc[im_export['year']==' '] << 이부분은 생각도 못함. # im_export12.sort_values(by='balPayments', ascending = False) << 여기서 잘못했잖아!! # im_export12.reset_index(drop = True , inplace = True) # im_export12.head(10) |
# 정답 # 2022년 12월 무역수지 TOP 10 im_export12 = im_export.loc[im_export['year'] == '2022.12',] im_export12 = im_export12.sort_values(by='balPayments', ascending = False) im_export12.reset_index(drop=True, inplace=True) im_export12.head(10) |
블로그 정보가 부족하면
[파이썬] 서울 공공데이터 포털 Open API를 이용해서 지하철 승차인원수 구하기 | Exobrain (gunn.kim)
[python] 공공 데이터 포털 API 불러오기 — 코딩하는 감자 (tistory.com)
이쪽에서 정보를 얻는 것이 좋을 것 같다. 나도 이쪽에서 수업에 필요한 정보를 얻었다.
반복이 제일 중요한 것 같다. 코드를 손에 익히는 느낌이랄까? 내림차순 정렬! 나오면 바로 .sort_values(by = ' ', ascending = False)가 내 손에서 나오도록 연습하는 게 중요하다고 한다. 강사님께서도 복사 붙여넣기는 본인만 하는 것이라고 하실만큼 반복이 중요하다는 것을 항상 생각하자.
'KT AIVLE School 3기 > Pandas' 카테고리의 다른 글
KT Aivle DX 트랙 20일차 (0) | 2023.02.28 |
---|---|
KT Aivle DX트랙 19일차 (0) | 2023.02.27 |
KT Aivle DX 트랙 17일차 (0) | 2023.02.23 |
KT Aivle DX 트랙 16일차 (0) | 2023.02.22 |
KT Alive DX 트랙 15일차 (0) | 2023.02.22 |