본문 바로가기
  • Homines, dum docent, discunt
  • Repetitio est Mater Memoriae
  • Dilige et fac quod vis
지식 창고/파이썬

미국 노동 통계청 API 활용법 Tip

by Manana Cho 2023. 6. 20.
반응형

[미국 노동 통계청 사이트]

https://www.bls.gov/

 

U.S. Bureau of Labor Statistics

Civilian workers' compensation costs average $43.07 per hour worked in March 2023 Employer costs for civilian workers averaged $29.70 per hour worked for wages and salaries and $13.36 for benefits in March 2023. Compensation costs were $16.54 at the 10th w

www.bls.gov

미국은 정보를 꽤나 투명하고 체계적으로 관리해 연구에 활용함에 있어 많은 도움이 됩니다. 그러나 미국 노동 통계청은 정말 최근의 데이터를 가지고 있음에도 불구하고, 데이터를 다운받는 것이 복잡하고 어려운 편에 속하는데, API를 쓰면 이런 문제는 줄어드나, API 활용 자체가 어렵더군요....ㅋㅋㅋㅋㅋㅋ

 

이번에 API 사용하면서 작성한 코드를 공유드립니다. 저는 주별로 전체 고용량 데이터가 필요해서 해당 데이터셋을 중심으로 코드를 작성했습니다. 그 외 데이터가 필요하신 분들은 이하의 주소들을 참고해서 코드를 작성해야 할 것 같습니다. 

1) API 활용방법에 대한 간략 설명

https://www.bls.gov/developers/api_signature_v2.htm#single

 

BLS Public Data API Signatures (Version 2.0) : U.S. Bureau of Labor Statistics

BLS Public Data API Signatures (Version 2.0) The BLS Public Data API utilizes the following three signatures: All signatures must include an HTTP type, a RESTful URL, and at least one series ID. The series ID(s) can include an underscore (_), dash (-) and

www.bls.gov

2) 각 필요한 데이터베이스 별로 METHOD 페이지가 있는데, 여기에 있는 통계표를 참고해서 데이터를 불러올 시리즈를 조합해 사용하셔야 합니다. 아래의 SERIES에 나온 바와 같습니다. 

예를 들어 설명드리자면 주별 CES 통계데이터를 가져오기 위해서는 해당 DB에 부여된 고유코드 SM이 둘째 자리까지  들어가고 계절별 조정이 들어가냐 아니냐에 따라 U(조정 안함) 혹은 S(조정함)을 셋째 자리에 넣습니다. 주별코드 두 자리와, 영역 코드(주로 볼 것이냐 경제 단위로 볼 것이냐)를 넣으면 10 번째 자리까지의 코드 조합이 나옵니다. 그리고 11번째에서 18번째자리까지 산업코드가 들어갑니다. 전산업의 경우 00000000 같은 숫자가 들어갈 수 있으며 데잌터 타입에 따라 마지막 둘째자리 숫자가 들어갑니다. 저는 이걸 생각하면서 코드를 짤 깜냥이 없어서 엑셀 표로 만들었습니다. 참고하실 분은 아래에 첨부해두겠습니다.   (연노랑색이 데이터 입력하는 부분, 형광노랑이 자동 시리즈 코드입니다.) 

BIScode.xlsx
0.04MB

 R이나, 파이썬, 다른 언어들을 사용해서 코드를 작성할 수 있으나 기본적으로 Json 을 이용해 데이터를 불러오는 방식이고, 기본 코드는 이하와 같습니다. API 신청을 하지 않고 기본 public api 로도 하루 500개? 가량의 데이터를 불러올 수 있습니다. 

1) 기본 패키지 불러오기

#Package 불러오기 (설치 할 때는 import 대신 !pip install [패키지명])

import pandas as pd

import os
import json
import csv

import requests
from prettytable import PrettyTable

2) public API 이용해서 데이터 불러오기 (Pretty Table 이용)

#Table 형태로 만드는 경우(추가로 수정하거나 계산할 경우라면 아래의 dataframe형태로 만드는 것을 추천드립니다.)

headers = {'Content-type': 'application/json'}

json_data = json.loads(p.text)
json_data
json_data = json.loads(p.text)
for series in json_data['Results']['series']:
    x=prettytable.PrettyTable(["series id","year","period","value","footnotes"])
    seriesId = series['seriesID']
    for item in series['data']:
        year = item['year']
        period = item['period']
        value = item['value']
        footnotes=""
        for footnote in item['footnotes']:
           if footnote:
               footnotes = footnotes + footnote['text'] + ','
       if 'M01' <= period <= 'M12':
           x.add_row([seriesId,year,period,value,footnotes[0:-1]])
   output = open(seriesId + '.txt','w')
   output.write (x.get_string())
   output.close()
x

--> 출력결과: 월별로 데이터가 나옴

2) public API 이용해서 데이터 불러오기 

#Dataframe 형태로 만드는 경우

#코드와, 시작일, 종료일을 넣고 dataframe으로 데이터 불러오기 

 

headers = {'Content-type': 'application/json'}
data = json.dumps({"seriesid": ['CODE'],'startyear':'2016', 'endyear':'2022'})
p = requests.post('https://api.bls.gov/publicAPI/v2/timeseries/data/', data=data, headers=headers)
p
json_data = json.loads(p.text)
for series in json_data['Results']['series']:
    seriesId = series['seriesID']
    data = []
    for item in series['data']:
        year = item['year']
        period = item['period']
        value = item['value']
        footnotes = ''
        for footnote in item['footnotes']:
            if footnote:
                footnotes = footnotes + footnote['text'] + ','
        if 'M01' <= period <= 'M12':
            data.append([seriesId, year, period, value, footnotes[:-1]])  # Remove the last comma from footnotes"
df = pd.DataFrame(data, columns=["series id", "year", "period", "value", "footnotes"])
df

 

#월별 데이터 -> 연도별 데이터로 묶기

df['year'] = pd.to_numeric(df['year'])
df['value'] = pd.to_numeric(df['value'])
grouped_00 = df.groupby(['series id','year']).agg({'value': 'mean'})
grouped_00

--> 출력결과: 연도별로 데이터가 나옴

3) 개인 API 이용해서 데이터 불러오기 

#아래 사이트에서 API를 신청하고 이메일로 활성화 시킨 뒤 이메일에 적힌 API 키를 아래 입력해주면 public 에서 허용하는 것 이상의 데이터를 불러올 수 있으며 단일 시리즈가 아닌, 여러 시리즈들을 불러오는 것도 가능

headers = {'Content-type': 'application/json'}
data = json.dumps({"seriesid": ['CODE, CODE2,...CODE_N '],'startyear':'2016', 'endyear':'2022','registrationkey': '[개인 API키 입력]'})

p = requests.post('https://api.bls.gov/publicAPI/v2/timeseries/data/', data=data, headers=headers)
p
json_data = json.loads(p.text)
for series in json_data['Results']['series']:
    seriesId = series['seriesID']
    data = []
    for item in series['data']:
        year = item['year']
        period = item['period']
        value = item['value']
        footnotes = ''
        for footnote in item['footnotes']:
            if footnote:
                footnotes = footnotes + footnote['text'] + ','
        if 'M01' <= period <= 'M12':
            data.append([seriesId, year, period, value, footnotes[:-1]])  # Remove the last comma from footnotes"
df = pd.DataFrame(data, columns=["series id", "year", "period", "value", "footnotes"])
df

 

* API 신청 페이지

https://data.bls.gov/registrationEngine/

 

Registration Engine

 

data.bls.gov

 

모쪼록 도움이 되셨길 바랍니다 :)

반응형

댓글