Problemdekomponering, grådige algoritmer og backtracking.
Databehandling og filhåndtering
I den virkelige verden ligger data sjelden ferdig i en Python-liste. Data lagres i filer, databaser og på nettet. For å bruke disse dataene må du kunne lese dem inn, behandle dem og ofte lagre resultatene tilbake.
I dette kapittelet skal du lære:
- Lese og skrive tekstfiler i Python
- Jobbe med CSV-filer (kommaseparerte verdier)
- Lese og skrive JSON-data
- Grunnleggende datarensing
- Introduksjon til pandas for dataanalyse
Disse ferdighetene er essensielle for alle som jobber med data, enten det er vitenskapelig forskning, webutvikling eller dataanalyse.
Grunnleggende konsepter:
Åpne en fil:
fil = open("filnavn.txt", modus)Moduser:
| Modus | Beskrivelse |
|---|---|
"r" | Lese (read) - standard |
"w" | Skrive (write) - overskriver filen |
"a" | Legge til (append) - legger til på slutten |
"x" | Opprett ny fil - feil hvis filen finnes |
Viktig: Bruk
with-blokk!# Anbefalt: with lukker filen automatisk
with open("data.txt", "r") as fil:
innhold = fil.read()
# Filen er nå lukket automatisk
# IKKE anbefalt: Må huske å lukke selv
fil = open("data.txt", "r")
innhold = fil.read()
fil.close() # Lett å glemme!Tegnsett (encoding):For norske tegn (æ, ø, å), bruk UTF-8:
with open("norsk.txt", "r", encoding="utf-8") as fil:
innhold = fil.read()# Skrive tekst til fil
with open("dagbok.txt", "w", encoding="utf-8") as fil:
fil.write("Dag 1: Lærte om filhåndtering\n")
fil.write("Dag 2: Lærte om CSV-filer\n")
fil.write("Dag 3: Lærte om JSON\n")
# Legge til mer tekst
with open("dagbok.txt", "a", encoding="utf-8") as fil:
fil.write("Dag 4: Lærte om pandas\n")Lese fra fil:
# Les hele filen som én streng
with open("dagbok.txt", "r", encoding="utf-8") as fil:
innhold = fil.read()
print(innhold)
# Les linje for linje
with open("dagbok.txt", "r", encoding="utf-8") as fil:
for linje in fil:
print(linje.strip()) # strip() fjerner \n
# Les alle linjer til en liste
with open("dagbok.txt", "r", encoding="utf-8") as fil:
linjer = fil.readlines()
print(linjer)
# ['Dag 1: ...\n', 'Dag 2: ...\n', ...]Praktisk eksempel: Behandle en loggfil
def analyser_logg(filnavn):
"""Analyserer en loggfil og teller feilmeldinger"""
feil_teller = 0
advarsel_teller = 0
with open(filnavn, "r", encoding="utf-8") as fil:
for linje in fil:
if "ERROR" in linje:
feil_teller += 1
elif "WARNING" in linje:
advarsel_teller += 1
print(f"Feil: {feil_teller}")
print(f"Advarsler: {advarsel_teller}")
# Lagre rapport
def lagre_rapport(filnavn, data):
"""Lagrer en rapport til fil"""
with open(filnavn, "w", encoding="utf-8") as fil:
fil.write("=== Rapport ===\n\n")
for nøkkel, verdi in data.items():
fil.write(f"{nøkkel}: {verdi}\n")
print(f"Rapport lagret til {filnavn}")
rapport = {"Antall brukere": 150, "Aktive i dag": 42, "Nye i uka": 12}
lagre_rapport("rapport.txt", rapport)Hva skriver denne koden til filen "tall.txt"?
with open("tall.txt", "w") as fil:
for i in range(1, 4):
fil.write(str(i * 10) + "\n")
with open("tall.txt", "a") as fil:
fil.write("Ferdig!")Eksempel på CSV-fil (elever.csv):
navn,alder,karakter
Anna,17,5
Bob,18,4
Charlie,17,6Hvorfor CSV?
- Enkelt og lesbart format
- Kan åpnes i Excel, Google Sheets, etc.
- Lett å eksportere fra databaser
- Standard format for datautveksling
Pythons csv-modul:
import csvViktige funksjoner:
- csv.reader() - Leser CSV som lister
- csv.DictReader() - Leser CSV som ordbøker
- csv.writer() - Skriver lister til CSV
- csv.DictWriter() - Skriver ordbøker til CSV
Vanlige problemer:
- Norske filer bruker ofte semikolon (;) som separator
- Tegnsett: Bruk UTF-8 for norske tegn
- Desimaltall: Norsk format bruker komma (3,14) vs punkt (3.14)
import csv
with open("elever.csv", "r", encoding="utf-8") as fil:
leser = csv.reader(fil)
overskrift = next(leser) # Hopp over overskriftsraden
print(f"Kolonner: {overskrift}")
for rad in leser:
navn, alder, karakter = rad
print(f"{navn} er {alder} år og har karakter {karakter}")Lese CSV med DictReader (anbefalt):
import csv
with open("elever.csv", "r", encoding="utf-8") as fil:
leser = csv.DictReader(fil)
for elev in leser:
print(f"{elev['navn']}: karakter {elev['karakter']}")DictReader bruker første rad som nøkler, så du kan referere til kolonner med navn.
Skrive CSV:
import csv
elever = [
{"navn": "Diana", "alder": 18, "karakter": 5},
{"navn": "Erik", "alder": 17, "karakter": 4},
{"navn": "Fiona", "alder": 18, "karakter": 6}
]
with open("nye_elever.csv", "w", encoding="utf-8", newline="") as fil:
felter = ["navn", "alder", "karakter"]
skriver = csv.DictWriter(fil, fieldnames=felter)
skriver.writeheader() # Skriv overskriftsrad
for elev in elever:
skriver.writerow(elev)Norsk CSV med semikolon:
import csv
# Les norsk CSV med semikolon
with open("norsk_data.csv", "r", encoding="utf-8") as fil:
leser = csv.reader(fil, delimiter=";")
for rad in leser:
print(rad)Praktisk eksempel: Beregne gjennomsnitt fra CSV
import csv
def beregn_snitt(filnavn, kolonne):
"""Beregner gjennomsnittet av en numerisk kolonne i CSV"""
verdier = []
with open(filnavn, "r", encoding="utf-8") as fil:
leser = csv.DictReader(fil)
for rad in leser:
verdier.append(float(rad[kolonne]))
snitt = sum(verdier) / len(verdier)
return round(snitt, 2)
snitt_karakter = beregn_snitt("elever.csv", "karakter")
print(f"Gjennomsnittskarakter: {snitt_karakter}")Du har en CSV-fil "temperaturer.csv" med dette innholdet:
by,temperatur
Oslo,5.2
Bergen,8.1
Tromsø,-3.4
Trondheim,4.7Skriv kode som leser filen og finner byen med høyest temperatur.
JSON-format:
{
"navn": "Anna",
"alder": 17,
"fag": ["matte", "norsk", "engelsk"],
"aktiv": true,
"adresse": {
"gate": "Storgata 1",
"by": "Oslo"
}
}JSON vs Python:
| JSON | Python |
|---|---|
object {} | dict |
array [] | list |
string "" | str |
| number | int/float |
| true/false | True/False |
| null | None |
Pythons json-modul:
import jsonViktige funksjoner:-
json.load(fil) - Les JSON fra fil-
json.loads(streng) - Les JSON fra streng-
json.dump(data, fil) - Skriv JSON til fil-
json.dumps(data) - Konverter til JSON-strengFordeler med JSON:
- Lesbart for mennesker
- Støtter nestede strukturer
- Standard format for web-APIer
- Støttes av nesten alle programmeringsspråk
import json
elever = [
{
"navn": "Anna",
"alder": 17,
"fag": ["matte", "norsk", "IT"],
"karakterer": {"matte": 5, "norsk": 4, "IT": 6}
},
{
"navn": "Bob",
"alder": 18,
"fag": ["matte", "engelsk"],
"karakterer": {"matte": 4, "engelsk": 5}
}
]
# Skriv til fil
with open("elever.json", "w", encoding="utf-8") as fil:
json.dump(elever, fil, indent=2, ensure_ascii=False)
# indent=2 gjør filen lesbar
# ensure_ascii=False bevarer norske tegnLese JSON fra fil:
import json
with open("elever.json", "r", encoding="utf-8") as fil:
elever = json.load(fil)
for elev in elever:
print(f"{elev['navn']} tar {len(elev['fag'])} fag")
for fag, karakter in elev['karakterer'].items():
print(f" {fag}: {karakter}")JSON fra streng (f.eks. fra web-API):
import json
json_streng = '{"by": "Oslo", "temperatur": 5.2, "nedbør": true}'
data = json.loads(json_streng)
print(data["by"]) # Oslo
print(data["temperatur"]) # 5.2
# Tilbake til streng
ny_streng = json.dumps(data, ensure_ascii=False)
print(ny_streng)Praktisk eksempel: Konfigurasjonsfil
import json
def les_konfig(filnavn="config.json"):
"""Leser konfigurasjon fra JSON-fil"""
try:
with open(filnavn, "r", encoding="utf-8") as fil:
return json.load(fil)
except FileNotFoundError:
# Returner standardverdier
return {"tema": "lys", "språk": "nb", "font_størrelse": 14}
def lagre_konfig(konfig, filnavn="config.json"):
"""Lagrer konfigurasjon til JSON-fil"""
with open(filnavn, "w", encoding="utf-8") as fil:
json.dump(konfig, fil, indent=2, ensure_ascii=False)
# Bruk
konfig = les_konfig()
konfig["tema"] = "mørk"
lagre_konfig(konfig)Hvilken påstand om CSV og JSON er riktig?
Vanlige problemer i reelle data:
| Problem | Eksempel | Løsning |
|---|---|---|
| Manglende verdier | tom celle, "N/A" | Fjerne rad eller fylle inn |
| Feil datatype | "atten" i stedet for 18 | Konvertere eller fjerne |
| Duplikater | Samme rad to ganger | Fjerne duplikater |
| Inkonsistent format | "Oslo", "oslo", "OSLO" | Standardisere |
| Whitespace | " Oslo " | strip() |
| Uteliggere | Alder: 999 | Vurdere og eventuelt fjerne |
Steg i datarensing:
1. Inspiser: Se på dataene, finn problemer
2. Valider: Sjekk datatyper, verdier og formater
3. Rens: Fiks problemer systematisk
4. Verifiser: Sjekk at rensingen var vellykket
Tommelregel: Du bruker ofte 80% av tiden på datarensing og bare 20% på selve analysen!
La oss rense et datasett med elever som har diverse problemer:
import csv
def les_og_rens(filnavn):
"""Leser CSV og renser dataene"""
renset_data = []
forkastet = 0
with open(filnavn, "r", encoding="utf-8") as fil:
leser = csv.DictReader(fil)
for rad in leser:
# 1. Fjern whitespace fra alle verdier
renset = {k: v.strip() for k, v in rad.items()}
# 2. Standardiser navn (stor forbokstav)
renset["navn"] = renset["navn"].title()
# 3. Sjekk manglende verdier
if not renset["navn"] or not renset["alder"]:
forkastet += 1
continue
# 4. Konverter og valider alder
try:
alder = int(renset["alder"])
if alder < 15 or alder > 20:
forkastet += 1
continue
renset["alder"] = alder
except ValueError:
forkastet += 1
continue
# 5. Konverter og valider karakter
try:
karakter = int(renset["karakter"])
if karakter < 1 or karakter > 6:
forkastet += 1
continue
renset["karakter"] = karakter
except ValueError:
renset["karakter"] = None # Manglende karakter OK
renset_data.append(renset)
print(f"Beholdt {len(renset_data)} rader, forkastet {forkastet}")
return renset_data
# Fjerne duplikater
def fjern_duplikater(data, nøkkel="navn"):
"""Fjerner duplikater basert på en nøkkel"""
sett = set()
unik = []
for rad in data:
if rad[nøkkel] not in sett:
sett.add(rad[nøkkel])
unik.append(rad)
return unikVanlige rensefunksjoner:
# Standardisere tekst
def rens_tekst(tekst):
"""Renser og standardiserer tekst"""
tekst = tekst.strip() # Fjern whitespace
tekst = tekst.lower() # Til lowercase
tekst = " ".join(tekst.split()) # Fjern ekstra mellomrom
return tekst
# Håndtere manglende verdier
def fyll_manglende(data, kolonne, standardverdi):
"""Fyller inn manglende verdier"""
for rad in data:
if rad[kolonne] is None or rad[kolonne] == "":
rad[kolonne] = standardverdi
return data
# Konvertere datoformat
def standardiser_dato(dato_tekst):
"""Konverterer ulike datoformater til standard"""
from datetime import datetime
formater = ["%d.%m.%Y", "%d/%m/%Y", "%Y-%m-%d"]
for fmt in formater:
try:
return datetime.strptime(dato_tekst, fmt).strftime("%Y-%m-%d")
except ValueError:
continue
return NoneDu har denne listen med data:
data = [
{"navn": " Anna ", "alder": "17", "karakter": "5"},
{"navn": "bob", "alder": "atten", "karakter": "4"},
{"navn": "Charlie", "alder": "18", "karakter": ""},
{"navn": "Anna", "alder": "17", "karakter": "5"},
{"navn": "Diana", "alder": "200", "karakter": "3"}
]Hvilke rader bør forkastes og hvorfor?
Hovedkonsepter:
DataFrame: En tabell med rader og kolonner (som et regneark)
import pandas as pd
df = pd.DataFrame({
"navn": ["Anna", "Bob", "Charlie"],
"alder": [17, 18, 17],
"karakter": [5, 4, 6]
})Series: En enkelt kolonne (som en liste med indeks)
alder = df["alder"] # SeriesHvorfor pandas?
- Raskere enn løkker for store datasett
- Innebygde funksjoner for datarensing
- Enkel fillesing (CSV, JSON, Excel, etc.)
- Kraftig filtrering og gruppering
- Statistiske funksjoner innebygd
Installasjon:
pip install pandasImport-konvensjon:
import pandas as pdimport pandas as pd
# Les fra CSV
df = pd.read_csv("elever.csv", encoding="utf-8")
# Les fra JSON
df = pd.read_json("elever.json", encoding="utf-8")
# Les norsk CSV med semikolon
df = pd.read_csv("norsk_data.csv", sep=";", encoding="utf-8")Inspeksjon av data:
import pandas as pd
df = pd.read_csv("elever.csv")
print(df.head()) # Første 5 rader
print(df.info()) # Kolonnetyper og manglende verdier
print(df.describe()) # Statistikk for numeriske kolonner
print(df.shape) # (antall_rader, antall_kolonner)
print(df.columns.tolist()) # KolonnenavnVelge data:
# Velg kolonne
navn = df["navn"]
# Velg flere kolonner
utvalg = df[["navn", "karakter"]]
# Filtrere rader
voksne = df[df["alder"] >= 18]
flinke = df[df["karakter"] >= 5]
# Kombinert filter
flinke_voksne = df[(df["alder"] >= 18) & (df["karakter"] >= 5)]Beregninger:
# Statistikk
print(df["karakter"].mean()) # Gjennomsnitt
print(df["karakter"].median()) # Median
print(df["karakter"].max()) # Maks
print(df["karakter"].min()) # Min
print(df["karakter"].std()) # Standardavvik
# Gruppering
per_alder = df.groupby("alder")["karakter"].mean()
print(per_alder)Datarensing med pandas:
# Fjern rader med manglende verdier
df_ren = df.dropna()
# Fyll inn manglende verdier
df["karakter"] = df["karakter"].fillna(df["karakter"].mean())
# Fjern duplikater
df_unik = df.drop_duplicates()
# Endre datatype
df["alder"] = df["alder"].astype(int)
# Standardiser tekst
df["navn"] = df["navn"].str.strip().str.title()Lagre resultat:
df.to_csv("resultat.csv", index=False, encoding="utf-8")
df.to_json("resultat.json", orient="records", force_ascii=False)Gitt denne DataFrame:
import pandas as pd
df = pd.DataFrame({
"navn": ["Anna", "Bob", "Charlie", "Diana", "Erik"],
"fag": ["matte", "norsk", "matte", "norsk", "matte"],
"karakter": [5, 4, 6, 5, 3]
})Hva gir df.groupby("fag")["karakter"].mean()?
Oppsummering
Filhåndtering:
- Bruk alltid with open(...) as fil: for automatisk lukking
- Moduser: "r" (les), "w" (skriv), "a" (legg til)
- Bruk encoding="utf-8" for norske tegn
CSV-filer:
- Tabellformat med rader og kolonner
- Bruk csv.DictReader() for enkel lesing
- Bruk csv.DictWriter() for skriving
- Husk delimiter=";" for norske filer
JSON:
- Støtter nestede strukturer (objekter og lister)
- json.load() / json.dump() for filer
- json.loads() / json.dumps() for strenger
- Bruk indent=2 for lesbarhet
Datarensing:
- Fjern whitespace: strip()
- Standardiser: lower(), title()
- Valider datatyper: try/except med int(), float()
- Håndter manglende verdier
- Fjern duplikater
pandas:
- pd.read_csv() / pd.read_json() for innlesing
- df.head(), df.info(), df.describe() for inspeksjon
- Filtrering: df[df["kolonne"] > verdi]
- Gruppering: df.groupby("kolonne").mean()
- Rensing: dropna(), fillna(), drop_duplicates()
Filformat-sammenligning:
| Format | Struktur | Bruksområde | Lesbarhet |
|---|---|---|---|
| TXT | Ustrukturert | Logger, notater | God |
| CSV | Flat tabell | Regneark, enkel data | God |
| JSON | Nestede objekter | APIer, konfigurasjon | God |
Samleoppgaver
Oppgaver som kombinerer filhåndtering, datarensing og analyse:
Du har en CSV-fil "salg.csv" med disse kolonnene: produkt, antall, pris, dato.
Beskriv stegene for en komplett databehandlingspipeline som:
1. Leser inn dataene
2. Renser dataene (håndterer manglende verdier og feil)
3. Beregner total omsetning per produkt
4. Lagrer resultatet som JSON
For hvert scenario, velg riktig filformat (TXT, CSV eller JSON) og begrunn valget:
A) Lagre en liste med 1000 temperaturer med tidspunkt og sted
B) Lagre brukerinnstillinger for en app (tema, språk, varsler, favoritter)
C) Lagre en loggfil med hendelser som skjer i et program
D) Eksportere data fra en database som skal åpnes i Excel
Dette kapitlet er skrevet av Anthropics toppmodeller (Claude Opus og Claude Fable) og er foreløpig ikke manuelt gjennomgått — kvalitetskontrollen gjøres av uavhengige KI-agenter, og innmeldte feil rettes fortløpende. Funnet en feil? Meld fra, så retter vi den. Les mer om hvordan innholdet lages.