본문 바로가기
Python/Data 처리

[python] OPEN API 데이터 불러오기 (JSON to Pandas DataFrame)

by 여비코기 2021. 5. 19.

우리나라 공공데이터 포털(https://www.data.go.kr)에서는 OPEN API 서버를 이용하여 각종 데이터들을 XML/JSON 형식으로 제공하고 있다. 사용방법은 회원가입 후 활용할 데이터를 신청하여 개인 Service Key를 받게 되면 공공데이터 포털 내 모든 데이터를 자유롭게 활용할 수 있다.

 

공공데이터 포털

국가에서 보유하고 있는 다양한 데이터를『공공데이터의 제공 및 이용 활성화에 관한 법률(제11956호)』에 따라 개방하여 국민들이 보다 쉽고 용이하게 공유•활용할 수 있도록 공공데이터(Datase

www.data.go.kr

 

나는 공공데이터 포털에서 기상청 종관 ASOS 시간 관측 자료를 활용하여 데이터를 살펴보려고 한다.

먼저 활용신청을 한 후, 데이터를 JSON형식으로 받은 후 Pandas DataFrame형식으로 변환하고 Matplotlib Plot으로 시각화 해볼 것이다.

 

from urllib.request import Request, urlopen
from urllib.parse import urlencode, quote_plus

OPEN API서버는 각종 정보가 담긴 url을 통해 접속하기 때문에 url을 다룰 모듈을 import해준다

 

url = 'http://apis.data.go.kr/1360000/AsosHourlyInfoService/getWthrDataList'
service_key='인코딩된 나의 service key'
queryParams = '?' + urlencode({quote_plus('ServiceKey') : service_key,
                               quote_plus('pageNo') : '1',
                               quote_plus('numOfRows') : '720',
                               quote_plus('dataType') : 'JSON',
                               quote_plus('dataCd') : 'ASOS', 
                               quote_plus('dateCd') : 'HR', 
                               quote_plus('startDt') : '20210101',
                               quote_plus('startHh') : '01',
                               quote_plus('endDt') : '20210131',
                               quote_plus('endHh') : '01',
                               quote_plus('stnIds') : '108' })

기본적으로 내가 받을 데이터의 주소(url)와 데이터의 범위와, 종류, 표시 형식등을 지정해줄 queryParams를 입력해준다.

나는 2021년 1월 1일 부터 2021년 1월 31일 까지의 서울(station id : 108)데이터를 JSON 형식으로 받기 위해 위와 같이 queryParams를 입력해 주었다. service key에는 자신의 키를 입력해주면 된다.

 

response = urlopen(url + queryParams)
json_api = response.read().decode("utf-8")

위에서 입력한 url과 queryParams를 붙혀 json_api라는 이름으로 자료를 요청하여 불러왔다. 이때 utf-8로 인코딩하지 않으면 제대로 불러와지지 않는 경우가 있어 인코딩 해주었다.

데이터를 불러와 출력해보면 다음과 같이 정리되지 않은 형태를 가지고 있다.

 

import pandas as pd
from pandas.io.json import json_normalize
import json

이제 위의 정리되지 않은 json웹 데이터를 pandas dataframe으로 정리해 볼 것이다.

 

json_file = json.loads(json_api)

위의 json_api 를 json.loads로 불러온 형태는 다음과 같이 출력된다.

이전의 원시 자료보다는 변수별로 데이터가 정리되 있는 모습을 확인 할 수 있다.

데이터의 구조를 살펴보면 다음과 같은 순서로 자료가 구성되어 있다.

response -> body -> items -> item

따라서 json_normalize를 통해 dataframe화 할때 가장 깊숙히 있는 item에 해당하는 데이터들을 불러와야 한다.

df=json_normalize(json_file['response']['body']['items']['item'])

위와 같이 데이터프레임으로 만들과 나는 df라고 지정해 주었다. 이를 출력하면 다음과 같다

 

가장 왼쪽 날짜-시간 열을 시작으로 데이터들이 잘 정렬된 것을 확인 할 수 있다.

 

과연 날짜순대로 데이터가 제대로 들어왔는지 확인해보기 위해 표면 기온과 풍속 데이터를 불러와 시각화 하여 확인해보려고 한다.

 

import matplotlib.pyplot as plt


df['tm']=pd.to_datetime(df['tm'])
df['ts'] = pd.to_numeric(df['ts'], downcast='float')

fig = plt.figure(figsize=(14,6))
ax = plt.subplot(1,1,1)

ax.plot(df['tm'],df['ts'],color='r',lw=1.5,alpha=0.7)
ax.set_ylabel('Temperature', fontweight='bold', fontsize=12)
ax.set_xlabel('Date', fontweight='bold', fontsize=12)
ax.set_title('OPEN API ASOS Temperature data', fontweight = 'bold',fontsize = 14)

시간 컬럼인 'tm'을 datetime으로 만들어주고, 표면 온도 컬럼인 'ts'는 object형식이기 때문에 float형태로 바꾸어 준다.

이후 time series를 그려보면 다음과 같다.

1월 한달의 날짜와 온도 데이터가 제대로 들어왔다. 하루에 밤과 낮이 바뀌면서 기온이 상승, 하락하는 패턴도 확인 할 수 있다.

 

표면 온도 외에 풍속 데이터도 한번 같이 확인해보자

 

df['ws'] = pd.to_numeric(df['ws'], downcast='float')

fig = plt.figure(figsize=(14,6))
ax = plt.subplot(1,1,1)
ax.plot(df['tm'],df['ws'],color='b',lw=1.5,alpha=0.7)
ax.set_ylabel('Wind Speed', fontweight='bold', fontsize=12)
ax.set_xlabel('Date', fontweight='bold', fontsize=12)
ax.set_title('OPEN API ASOS Wind Speed data', fontweight = 'bold',fontsize = 14)

역시 잘들어왔다. 두 데이터의 대략적인 상관성이 있을까?

 

fig = plt.figure(figsize=(14,6))
ax = plt.subplot(1,1,1)

ax.plot(df['tm'],df['ts'],color='r',lw=1.5,alpha=0.8)
ax.set_ylabel('Temprature', fontweight='bold', fontsize=12)
ax.set_xlabel('Date', fontweight='bold', fontsize=12)
ax.set_title('OPEN API ASOS Temperature & Wind Speed', fontweight = 'bold',fontsize = 14)


ax2 = ax.twinx()  
ax2.plot(df['tm'],df['ws'],color='b',lw=1.5,alpha=0.8)
ax2.set_ylabel('Wind Speed', fontweight='bold', fontsize=12)

이것만 봐서는 둘의 상관성을 크게 파악하긴 힘들다. 추후 스펙트럼 분석이나 기타 분석을 통해 풍속이 올라간 이후 기온이 떨어진다던가 하는 상관관계의 분석도 가능하지만 이번 단계에서는 데이터를 불러와 살펴보는 정도로 마치려고 한다.

 

공공데이터 포털의 데이터의 종류는 수없이 많아서 각종 데이터들을 활용하여 어플을 만들거나, 분석을 하거나, 기타 자료로 활용하는 등 다양한 분야의 활용 방법이 있다. 나도 이러한 것을 이용해서 어떤 것을 활용해 볼지 항상 생각중이다. 떠오르는 아이디어가 있으면 게시글로 남겨보고자 한다.

 

댓글