Les 1 · Module 1 · pandas-basis
Je eerste analyse: van CSV naar antwoord
Zet een pandas-project op, lees de verkoopgegevens van een schoolkantine in en beantwoord je eerste vraag: welke categorie levert het meeste op?
🎯 Na deze les kun je
- een project met een virtuele omgeving en pandas opzetten
- een CSV-bestand inlezen en de vorm en typen van de gegevens controleren
- een berekende kolom maken en met groupby een vraag beantwoorden
- het resultaat opslaan als nieuw CSV-bestand
Een spreadsheet is prima zolang je gegevens klein en netjes zijn. Maar zodra je honderdduizend rijen hebt, elke maand hetzelfde rapport moet maken, of wilt kunnen uitleggen hoe je aan een getal komt, wil je een script: een analyse die je opnieuw kunt draaien en die precies laat zien wat er gebeurt. pandas is de Python-bibliotheek die daarvoor overal gebruikt wordt, van stagebedrijf tot onderzoeksinstituut.
In deze cursus werk je steeds aan één project: de verkoopgegevens van een schoolkantine. In deze eerste les zet je het project op en beantwoord je meteen een echte vraag: welke categorie levert het meeste op?
Wat je nodig hebt
- Python 3.11 of nieuwer (
python3 --version) - Een terminal en een editor
- Kennis van lijsten, dicts, functies, bestanden en
pipuit Een beetje Python. Les 27 daar (pandas in één les) is handig, maar niet nodig: we beginnen bij het begin.
Project opzetten
Maak een map en een virtuele omgeving, zodat de pakketten van dit project los blijven van de rest van je computer:
mkdir kantine-analyse && cd kantine-analyse
python3 -m venv .venv
source .venv/bin/activate # Windows: .venv\Scripts\activate
pip install pandas
python -c "import pandas; print(pandas.__version__)"
Je ziet een versienummer, bijvoorbeeld 2.2.3. Leg vast welke versie je gebruikt, dan werkt je analyse
over een jaar nog hetzelfde:
pip freeze > requirements.txt
Maak nu het bestand kantine.csv met de verkopen van drie dagen. Elke regel is één product op één dag:
datum,product,categorie,aantal,prijs
2026-09-07,broodje kaas,eten,14,2.10
2026-09-07,tosti,eten,9,2.50
2026-09-07,appel,fruit,6,0.60
2026-09-07,chocomel,drinken,11,1.40
2026-09-08,broodje kaas,eten,12,2.10
2026-09-08,tosti,eten,15,2.50
2026-09-08,water,drinken,8,1.00
2026-09-08,chocomel,drinken,10,1.40
2026-09-09,broodje kaas,eten,16,2.10
2026-09-09,appel,fruit,4,0.60
2026-09-09,tosti,eten,7,2.50
2026-09-09,water,drinken,13,1.00
Eerst kijken, dan rekenen
De belangrijkste gewoonte van een analist: kijk eerst of de gegevens zijn wat je denkt. Maak verken.py:
import pandas as pd
df = pd.read_csv("kantine.csv")
print(df.head(3))
print(df.shape)
print(df.dtypes)
Voorspel eerst: hoeveel rijen en kolommen heeft de tabel, en welk type krijgt de kolom datum?
datum product categorie aantal prijs
0 2026-09-07 broodje kaas eten 14 2.1
1 2026-09-07 tosti eten 9 2.5
2 2026-09-07 appel fruit 6 0.6
(12, 5)
datum object
product object
categorie object
aantal int64
prijs float64
dtype: object
pd.read_csvleest het bestand in een DataFrame: een tabel met benoemde kolommen en een index (de nummers 0, 1, 2 links).df.head(3)toont de eerste drie rijen. Doe dit altijd na het inlezen.df.shapeis(rijen, kolommen): 12 rijen, 5 kolommen.df.dtypestoont per kolom het type.aantalis een geheel getal (int64),prijseen kommagetal (float64).objectbetekent hier: tekst.
Viel je op dat datum tekst is? pandas raadt geen datums, tenzij je het vraagt. Voor rekenen met datums
(per week, per maand) moet het echt een datum zijn. Dat regel je bij het inlezen met parse_dates.
Uitgewerkt voorbeeld: omzet per categorie
De vraag: welke categorie levert het meeste op? Daarvoor heb je per rij de omzet nodig (aantal × prijs),
en daarna de som per categorie. Maak analyse.py:
import pandas as pd
df = pd.read_csv("kantine.csv", parse_dates=["datum"])
df["omzet"] = df["aantal"] * df["prijs"]
per_categorie = df.groupby("categorie")["omzet"].sum().sort_values(ascending=False)
print(per_categorie)
print()
print("Totaal:", round(df["omzet"].sum(), 2))
print("Beste dag:", df.groupby("datum")["omzet"].sum().idxmax().date())
per_categorie.round(2).to_csv("omzet_per_categorie.csv")
categorie
eten 165.7
drinken 50.4
fruit 6.0
Name: omzet, dtype: float64
Totaal: 222.1
Beste dag: 2026-09-08
En in omzet_per_categorie.csv staat:
categorie,omzet
eten,165.7
drinken,50.4
fruit,6.0
Wat gebeurt er precies?
df["omzet"] = df["aantal"] * df["prijs"]
Maakt een nieuwe kolom: voor elke rij tegelijk aantal × prijs, zonder lus.df.groupby("categorie")
Verdeelt de rijen in groepjes per categorie.["omzet"].sum()
Telt binnen elk groepje de omzet op; het resultaat is een Series met de categorie als index..sort_values(ascending=False)
Hoogste bedrag eerst..idxmax()
De index (hier: de datum) van de hoogste waarde..to_csv(...)
Schrijft het resultaat weg, zodat je het kunt delen of in een volgende stap kunt gebruiken.
Het rekenen op een hele kolom tegelijk heet gevectoriseerd rekenen. Het is korter dan een lus en bij grote bestanden veel sneller, omdat pandas het werk in geoptimaliseerde code onder water doet. Een kolom op zichzelf is een Series: een rij waarden met een index. Een DataFrame is een verzameling Series met dezelfde index.
Als je de hoofdcursus hebt gedaan: groupby is precies het "tellen per sleutel"-patroon met een dict,
en GROUP BY in SQL. Zelfde concept, derde schrijfwijze.
Oefenen
Oefening 1. Welk product is het vaakst verkocht (in stuks, over alle dagen)? Schrijf één regel pandas.
Modelantwoord oefening 1
print(df.groupby("product")["aantal"].sum().sort_values(ascending=False).head(1))
product
broodje kaas 42
Name: aantal, dtype: int64
Groeperen op product, de aantallen optellen, sorteren van hoog naar laag en de eerste rij nemen.
Oefening 2. Hoeveel drankjes zijn er in totaal verkocht? Gebruik een filter op de kolom categorie.
Modelantwoord oefening 2
drinken = df[df["categorie"] == "drinken"]
print(drinken["aantal"].sum())
42
df["categorie"] == "drinken" geeft per rij True of False; df[...] houdt alleen de rijen met True over.
Filteren komt uitgebreid terug in les 5.
Oefening 3. Maak een overzicht van de omzet per dag, afgerond op twee decimalen, en sla het op als omzet_per_dag.csv.
Modelantwoord oefening 3
per_dag = df.groupby("datum")["omzet"].sum().round(2)
print(per_dag)
per_dag.to_csv("omzet_per_dag.csv")
datum
2026-09-07 70.9
2026-09-08 84.7
2026-09-09 66.5
Name: omzet, dtype: float64
Lokaal oefenen
Breid analyse.py uit zodat het ook de omzet per product toont, van hoog naar laag. Voeg daarna zelf
twee dagen toe aan kantine.csv en draai het script opnieuw. Dat is meteen de kracht van een script: nieuwe
gegevens, zelfde analyse, één commando.
Typische fouten
KeyError: 'Omzet'
De kolomnaam klopt niet. Kolomnamen zijn hoofdlettergevoelig; kijk metprint(df.columns)hoe ze echt heten.KeyError: 'Column not found: omzet'
Je groepeert op een kolom die nog niet bestaat. Maak de berekende kolom vóór degroupby.FileNotFoundError: [Errno 2] No such file or directory: 'kantien.csv'
Tikfout in de bestandsnaam, of je draait het script vanuit een andere map dan waar het CSV-bestand staat.- Je DataFrame heeft maar één kolom met alles erin
Het bestand gebruikt een ander scheidingsteken (vaak;bij een Nederlandse Excel-export). Gebruikpd.read_csv("bestand.csv", sep=";").
Samenvatting
- Een analyse in een script kun je opnieuw draaien, controleren en delen. Leg je pakketversies vast in
requirements.txt. pd.read_csvmaakt een DataFrame; controleer altijd eerst methead(),shapeendtypes.- Datums lees je in met
parse_dates, anders zijn het gewoon teksten. - Rekenen op hele kolommen tegelijk (
df["a"] * df["b"]) is korter en sneller dan een lus. groupby(...)[...].sum()beantwoordt "hoeveel per …?"-vragen;to_csvbewaart het resultaat.
In les 2 kijk je onder de motorkap: wat zijn index, kolommen en dtypes precies, en waarom maakt dat uit voor alles wat je hierna doet?