Jobbe med data
I denne artikkelen viser vi hvordan man leser og skriver forskjellige filtyper på Dapla med Python og R. Vi har skrevet egne artikler for deling av data, flytting av data mellom bøtter (transfer service), pseudonymisering. Vi har også skrevet om kartdata og datavalidering med pandera.
Lese og skrive data på Dapla
Vi bruker Python og R når vi skal lese, skrive og bearbeide data. Dette må gjøres fra en av Dapla lab-tjenestene (for eksempel jupyter). Dette er fordi Dapla lab er koblet opp mot Google Cloud Storage.
Tidligere har vi vært avhengige av Python-pakken dapla-toolbelt og R-pakken fellesR. Nå trenger man ikke ta spesielle hensyn: man leser og skriver data som om man jobber lokalt. Man bruker altså pandas for Python og arrow for R.
Bøttemontering og teamtilhørighet
For å få tilgang til data på Google Cloud må man kjøre Python/R fra Dapla lab. Første steg er altså å starte en instans av VSCode, Jupyter eller RStudio fra Dapla lab.
Når man starter tjenesten må man være obs på hvilket team man representerer i den tjenesten. På dapla styres datatilgang etter Dapla team. Du må derfor velge riktig dapla team under tjenestekonfigurasjonen. Tjenestekonfigurasjonen kan du lese om i blant annet jupyter-artikkelen vår.

Man må naturligvis vite hvor dataene ligger, men vi trenger ikke hele filstien! Dapla lab er bøttemontert: det vil si at vi kan forenkle filstier til buckets/{bøttenavn}/{filnavn}
(gs://ssb-dapla-felles-data-produkt-prod
er ikke lenger nødvendig å ha i filstien).
Dapla Felles er et team der alle i SSB er med i developers-gruppa. Kode-eksemplene finnes for både R og Python, og du kan velge hvilken du skal se ved å trykke på den arkfanen du er interessert i.
Lese og skrive filer
Under finner du eksempler på hvordan du kan lese og skrive data på Dapla. Kode-eksemplene finnes for både R og Python og du kan velge hvilken du skal se ved å trykke på den arkfanen du er interessert i.
Parquet
notebook
import pandas as pd
= "/buckets/produkt/datadoc/brukertest/10/sykefratot/klargjorte-data/person_testdata_p2021_v1.parquet"
file_path
# Les med pd.read_parquet()
= pd.read_parquet(file_path)
df
# Skriv med to_parquet()
df.to_parquet(file_path )
notebook
library(arrow)
= "/buckets/produkt/datadoc/brukertest/10/sykefratot/klargjorte-data/person_testdata_p2021_v1.parquet"
file_path
# Les med arrow::read_parquet()
<- arrow::read_parquet(file_path)
person_testdata
# Skriv med arrow::write_parquet()
::write_parquet(person_testdata, file_path) arrow
Vi kan også filtrere hvilke variabler vi ønsker å lese inn ved å spesifisere parameter col_select
. For eksempel:
<- arrow::read_parquet(file_path,
person_testdata col_select = c("fnr", "sivilstand"))
Kartdata lagret som .parquet kan leses inn ved å kombinere funksjonen open_dataset fra pakken arrow og read_sf_dataset fra pakken sfarrow.
library(arrow)
library(sfarrow)
library(tidyverse)
<- arrow::open_dataset("/buckets/produkt/GIS/Kart/2023/ABAS_grunnkrets_flate_2023/ABAS_grunnkrets_flate_2023.parquet") %>%
data ::filter(KOMMUNENR == "0301") %>%
dplyr::read_sf_dataset() sfarrow
Tekstfiler
notebook
import pandas as pd
= "/buckets/produkt/dapla-manual-examples/purchases.csv"
file_path
# Les med pd.read_csv()
= pd.read_csv(file_path, sep=';')
df
# Skriv med df.to_csv()
df.to_csv(file_path)
notebook
import pandas as pd
= "/buckets/produkt/dapla-manual-examples/test.json"
file_path
# Les med pd.read_json()
= pd.read_json(file_path)
df
# Skriv med df.to_json()
df.to_json(file_path)
notebook
= "/buckets/produkt/dapla-manual-examples/purchases.csv"
file_path
# Les med read.csv2()
<- read.csv2(file_path) #bruk read.csv2 for semikolonseparerte filer
dt_1987 # OBS: bruk read.csv() for kommaseparerte filer
# Skriv med write.csv2()
write.csv2(dt_1987, file_path)
notebook
library(jsonlite)
= "/buckets/produkt/dapla-manual-examples/test.json"
file_path
# Les med jsonlite::fromJSON()
<- jsonlite::fromJSON(file_path)
data
# Skriv med jsonlite::write_json()
::write_json(data, file_path) jsonlite
xlsx
notebook
import pandas as pd
= "/buckets/produkt/dapla-manual-examples/test.xlsx"
file_path
# Les med pd.read_excel()
= pd.read_excel(file_path)
df
# Skriv med df.to_excel()
df.to_excel(file_path)
XLSX-filer kan leses inn med funksjonen read.xlsx fra pakken openxlsx.
notebook
library(openxlsx)
= "/buckets/produkt/dapla-manual-examples/purchases.xlsx"
file_path
# Les med openxlsx::read.xlsx()
<- openxlsx::read.xlsx(file_path)
data
# Skriv med openxlsx::write.xlsx()
::write.xlsx(data, file_path) openxlsx
SAS
Her er et eksempel på hvordan man leser inn en sas7bdat-fil på Dapla som har blitt generert i prodsonen.
notebook
import dapla as dp
= "/buckets/produkt/dapla-manual-examples/statbank_ledstill.sas7bdat"
file_path
# Les med pd.read_sas()
format="sas7bdat", encoding="latin1") pd.read_sas(file_path,
Legg merke til at det ikke lenger er nødvendig med full filsti. I tilfellene vist over ville man tidligere skrevet filstiene på denne måten: gs://ssb-dapla-felles-data-produkt-prod/dapla-metrics/test.parquet
Nå skjønner maskinen at den skal lete under ssb-dapla-felles fordi dette er teamet vi valgte under tjenestekonfigurasjon
Så enkelt er det! Men…
Når vi jobber med data på dapla må vi ta stilling til og følge obligatoriske standarder, for eksempel navnestandarden. Versjonering av datasett er viktig i denne sammenheng. Å jobbe med data krever i praksis mer enn de tekniske ferdighetene til å lese, behandle og skrive data.
For å lære hvordan du bruker R og Python til databehandling må man foreløpig ut av manualen. Vi anbefaler at du bruker deler av dokumentet Kom i gang med Dapla skrevet av A200 støtteteam og boken R for Data Science.
Filbehandling
Slette filer
Å slette filer fra lagringsområdet kan gjøres på flere måter. Man kan gjøre det med pek-og-klikk i Google Cloud Console eller med Python og R:
notebook
import os
= "fil/sti.parquet"
file_path
os.remove(file_path)
Funksjonen file.remove
kan brukes til å slette data på lagringsområdet.
notebook
# Skriv inn full filsti til filen som skal slettes
= "fil/sti.parquet"
file_path
file.remove(file_path)
Kopiere filer
notebook
import shutil
# Path to folders
= "/buckets/produkt/felles/veiledning/python/eksempler/purchases"
from_folder = "/buckets/produkt/felles/veiledning/python/eksempler"
to_folder
# Copy file
f"{from_folder}/data.parquet",
shutil.copy(f"{to_folder}/data_copy.parquet")
Dette fungerer også for å kopiere filer mellom bøtter.
Console
# Skriv inn filnavn på filen som skal flytte og navn på bøtta hvor filen ligger.
= "purchases.csv"
file_name = "/buckets/produkt/dapla_manual-examples/"
bucket_path_gammel
#Skriv inn ny (hvis ikke bøtta finnes må den opprettes - se Opprette mapper under)
= "/buckets/produkt/dapla_manual-examples/ny_mappe/"
bucket_path_ny
#Hvis du bare vil endre plassering skriver du:
file.copy(from = paste0(bucket_path_gammel,file_name), to = paste0(bucket_path_ny,file_name))
#Hvis du også vil endre navnet på filen kan du skrive:
= "innkjoep.csv"
new_name file.copy(from = paste0(bucket_path_gammel,file_name), to = paste0(bucket_path_ny,new_name))
Merk at funksjonen file.copy() bevarer den opprinnelige filen. Hvis du heller ønsker å flytte filen (dvs å kopiere og slette den opprinnelige filen) velg file.rename().
Flytte (klippe/lime) filer
notebook
import shutil
# Path to folders
= "/buckets/produkt/felles/veiledning/python/eksempler/purchases"
from_folder = "/buckets/produkt/felles/veiledning/python/eksempler"
to_folder
# Copy file
f"{from_folder}/data.parquet",
shutil.move(f"{to_folder}/data.parquet")
Console
# Skriv inn filnavn på filen som skal flyttes og navn på bøtta hvor filen ligger nå.
= "purchases.csv"
file_name = "/buckets/produkt/dapla_manual-examples/"
bucket_path_gammel
#Skriv inn navn på den nye plasseringen (hvis ikke bøtta finnes må den opprettes - se Opprette mapper under)
= "/buckets/produkt/dapla_manual-examples/ny_mappe/"
bucket_path_ny
#Hvis du bare vil endre plassering skriver du:
file.rename(from = paste0(bucket_path_gammel,file_name), to = paste0(bucket_path_ny,file_name))
#Hvis du også vil endre navnet på filen kan du skrive:
= "innkjoep.csv"
new_name file.rename(from = paste0(bucket_path_gammel,file_name), to = paste0(bucket_path_ny,new_name))
Merk at funksjonen file.rename() sletter den opprinnelige filen. Hvis du bare vil kopiere uten å slette den opprinnelige filen velg file.copy().
Opprette mapper
Selv om bøtter ikke har mapper med en hierarkisk struktur slik man er kjent med fra klassiske filsystemer, så kan man opprette det som ser ut som mapper i objektnavnet. I realiteten blir bare /
oppfattet som en del av navnet på objektet. Skulle du likevel ønske å opprette dette så kan du gjøre det følgende måte:
notebook
import os
#Path to folder
= '/buckets/produkt/felles/veiledning/python/eksempler/testmappe/'
new_folder_path
# Create folder
os.mkdir(new_folder_path)
Console
# Skriv inn navnet på den nye mappen.
= "/buckets/produkt/dapla_manual-examples/testmappe/"
ny_mappe dir.create(ny_mappe)