#!/usr/bin/env python
# coding: utf-8
# Jupyter notebook versjon ligger på https://github.com/janbrus/ssb-api-python-examples
# Hente tabeller med datokonvertering
# Eksempel Nasjonalregnskap. Tabellene for nasjonalregnskap har egenskapen at de har lik struktur men ulik frekvens.
# Da kan vi enkelt bruke samme spørring, og poste den mot ulike tabellers metadata for å hente tall
# Makroøkonomiske hovedstørrelser:
# - [09189](https://www.ssb.no/statbank/table/09189) - årlig
# - [09190](https://www.ssb.no/statbank/table/09190) - kvartalsvis
# - [11721](https://www.ssb.no/statbank/table/11721) - månedlig
# Først importerer vi ulike pakker
import requests
import pandas as pd
from pyjstat import pyjstat # pyjstat er for behandling av JSON-stat
# URL til tabellenes metadata i PxWebApi, som vi skal poste spørringene mot
tabid = "09190" # prøv å kjøre med id for både år (09189), kvartal (09190) og måned (11721)
lang = "no" # vi kan velge "en"
url1 = "https://data.ssb.no/api/v0/" + lang + "/table/" + tabid;
# Vi spør etter årlig volumendring for BNP og BNP Fastlandsnorge for perioden 2010-2029 med filter all.
# API-spørring formulert som JSON.
query1 = {
"query": [
{
"code": "Makrost",
"selection": {
"filter": "item",
"values": [
"bnpb.nr23_9",
"bnpb.nr23_9fn"
]
}
},
{
"code": "ContentsCode",
"selection": {
"filter": "item",
"values": [
"Volum"
]
}
},
{
"code": "Tid",
"selection": {
"filter": "all",
"values": [
"201*",
"202*"
]
}
}
],
"response": {
"format": "json-stat2"
}
}
##########################
# Funksjon for identifiserer frekvens slik at vi kan konvertere til datoformat. Da kan vi kan sette Pandas RangeIndex
#funksjon for frekvenser
def dateConv(dataframe):
frekvens, frek_no, frek_en, fmt = findFrequency(dataframe)
setPeriodIndex(frekvens, frek_no, frek_en, fmt, dataframe)
def findFrequency(dataframe):
frekvenser = ['måned', 'kvartal', 'uke', 'år', 'year', 'quarter', 'month', 'week']
frek_no = '' #SSB bruker dessverre norske frekvenskode U - uke osv.
frek_en = '' #engelsk frekvens kode
fmt = '' # python datoformat
for w in frekvenser:
if w in dataframe.columns:
if w in ['måned', 'month']:
frek_no = 'M'
frek_en = 'M'
fmt = '%YM%m'
elif w in ['kvartal', 'quarter']:
frek_no = 'K'
frek_en = 'Q'
elif w in ['uke', 'week']:
frek_no = 'U';
frek_en = 'W'
fmt = '%YW%W-%w'
else:
frek_no = ''
frek_en = 'A'
return w, frek_no, frek_en, fmt
def setPeriodIndex(frekvens, frek_no, freq_en, fmt, df):
if frekvens in ['kvartal', 'quarter']:
# erstatter K med Q, konverterr til datoformat og setter frekensen til Pandas PeriodIndex
df.index = pd.PeriodIndex(pd.to_datetime(df[frekvens].str.replace(frek_no, freq_en), errors='coerce'), freq='Q-DEC')
elif frekvens in ['uke', 'week']:
df.index = pd.PeriodIndex(pd.to_datetime(df[frekvens].str.replace(frek_no, freq_en).add('-0'), format= fmt, errors='coerce'), freq='W-MON')
else:
df.index = pd.PeriodIndex(pd.to_datetime(df[frekvens], format= fmt, errors='coerce'), freq=freq_en)
############ slutt funksjoner ##########
# Her poster vi spørringen
res1 = requests.post(url1, json=query1)
# Leser resultatet med biblioteket pyjstat
ds1 = pyjstat.Dataset.read(res1.text)
# Skriver resultatet til en Pandas dataframe
df1 = ds1.write('dataframe')
df1.head(7)
# Kaller funksjonen dateConv som konverterer til dato
# Gjør en konvertering fra kategori til datoformat. Deretter settes denne som index med bruk av Pandas PeriodIndex
dateConv(df1)
# Nå har vi fått en Pandas PeriodIndex
df1.info()
# Plot med pandas groupby - gir to figurer
df1.groupby('makrostørrelse').plot( use_index=True, y='value', marker="o", markersize=3)
# ### pivoterer datasettet for å få èn figur
df2 = df1.pivot(columns = 'makrostørrelse', values='value')
# Øker størrelsen og setter SSB-farger
df2.plot(figsize=(16, 8), color=['#1a9d49', '#1d9de2'], title="BNP årlig volumendring %")