Data Science Met Python: Pandas & Numpy

Duik in de wereld van data analyse met Python's krachtigste libraries

Introductie tot Data Science

Data Science is een van de snelst groeiende vakgebieden in de technologie. Met de explosieve groei van data in onze digitale wereld, is de vraag naar data scientists enorm. Python is de meest populaire taal voor data science, voornamelijk dankzij krachtige libraries zoals NumPy, Pandas, en Matplotlib.

In dit artikel leren we de fundamenten van data analyse met Python, waarbij we ons richten op de twee belangrijkste libraries: NumPy voor numerieke berekeningen en Pandas voor data manipulatie.

Waarom NumPy?

NumPy (Numerical Python) is de basis van vrijwel alle data science libraries in Python. Het biedt:

  • Snelle arrays: Tot 100x sneller dan Python lists
  • Wiskundige functies: Uitgebreide set van mathematische operaties
  • Broadcasting: Efficiënte operaties op arrays van verschillende grootte
  • Memory efficiency: Optimaal geheugengebruik

NumPy Installeren en Importeren

# Installatie via pip
# pip install numpy

import numpy as np

# Eerste numpy array maken
arr = np.array([1, 2, 3, 4, 5])
print(arr)
print(type(arr))  # <class 'numpy.ndarray'>

NumPy Arrays Maken

# Verschillende manieren om arrays te maken
import numpy as np

# Van een Python list
list_data = [1, 2, 3, 4, 5]
arr1 = np.array(list_data)

# 2D array (matrix)
matrix = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
print("2D Array:")
print(matrix)

# Arrays met specifieke waarden
zeros = np.zeros((3, 4))  # 3x4 array gevuld met nullen
ones = np.ones((2, 3))    # 2x3 array gevuld met enen
full = np.full((2, 2), 7) # 2x2 array gevuld met 7

# Arrays met ranges
range_arr = np.arange(0, 10, 2)  # [0, 2, 4, 6, 8]
linspace_arr = np.linspace(0, 1, 5)  # 5 punten tussen 0 en 1

# Random arrays
random_arr = np.random.random((3, 3))  # 3x3 random getallen
random_int = np.random.randint(1, 10, (2, 4))  # 2x4 random integers 1-9

print("Range array:", range_arr)
print("Linspace array:", linspace_arr)
print("Random array:")
print(random_arr)

Array Eigenschappen en Indexing

import numpy as np

# Een sample array maken
arr = np.random.randint(1, 20, (4, 5))
print("Sample array:")
print(arr)

# Eigenschappen
print(f"Shape: {arr.shape}")      # Dimensies
print(f"Size: {arr.size}")        # Totaal aantal elementen
print(f"Ndim: {arr.ndim}")        # Aantal dimensies
print(f"Dtype: {arr.dtype}")      # Data type

# Indexing en slicing
print(f"Element [0,0]: {arr[0, 0]}")     # Eerste element
print(f"Eerste rij: {arr[0, :]}")        # Hele eerste rij
print(f"Eerste kolom: {arr[:, 0]}")      # Hele eerste kolom
print(f"Sub-matrix:")
print(arr[1:3, 2:4])                     # Submatrix

NumPy Operaties

import numpy as np

# Sample arrays
arr1 = np.array([1, 2, 3, 4, 5])
arr2 = np.array([6, 7, 8, 9, 10])

# Elementwise operaties
print("Optellen:", arr1 + arr2)
print("Vermenigvuldigen:", arr1 * arr2)
print("Kwadrateren:", arr1 ** 2)

# Statistische functies
data = np.random.normal(100, 15, 1000)  # 1000 punten, mean=100, std=15
print(f"Gemiddelde: {np.mean(data):.2f}")
print(f"Mediaan: {np.median(data):.2f}")
print(f"Standaarddeviatie: {np.std(data):.2f}")
print(f"Minimum: {np.min(data):.2f}")
print(f"Maximum: {np.max(data):.2f}")

# Matrix operaties
matrix1 = np.random.randint(1, 10, (3, 3))
matrix2 = np.random.randint(1, 10, (3, 3))

print("Matrix 1:")
print(matrix1)
print("Matrix 2:")
print(matrix2)
print("Matrix vermenigvuldiging:")
print(np.dot(matrix1, matrix2))

Pandas: Data Manipulatie Made Easy

Pandas is gebouwd bovenop NumPy en biedt data structuren en operaties voor het manipuleren van numerieke tabellen en tijdseries. De twee hoofdcomponenten zijn:

  • Series: Een 1-dimensionale array met labels
  • DataFrame: Een 2-dimensionale tabel (zoals Excel)

Pandas Installeren en Importeren

# Installatie via pip
# pip install pandas

import pandas as pd
import numpy as np

# Een Series maken
s = pd.Series([1, 3, 5, np.nan, 6, 8])
print("Series:")
print(s)

DataFrames Maken en Verkennen

import pandas as pd
import numpy as np

# DataFrame van dictionary
data = {
    'Naam': ['Alice', 'Bob', 'Charlie', 'Diana', 'Eva'],
    'Leeftijd': [25, 30, 35, 28, 32],
    'Stad': ['Brussel', 'Antwerpen', 'Gent', 'Brussel', 'Leuven'],
    'Salaris': [45000, 52000, 48000, 51000, 49000],
    'Department': ['IT', 'Finance', 'IT', 'HR', 'Finance']
}

df = pd.DataFrame(data)
print("DataFrame:")
print(df)

# Basis informatie
print("\nDataFrame info:")
print(f"Shape: {df.shape}")
print(f"Columns: {list(df.columns)}")
print(f"Data types:")
print(df.dtypes)

# Eerste en laatste rijen
print("\nEerste 3 rijen:")
print(df.head(3))

print("\nLaatste 2 rijen:")
print(df.tail(2))

# Statistische samenvatting
print("\nStatistische samenvatting:")
print(df.describe())

Data Selectie en Filtering

import pandas as pd

# Sample data
data = {
    'Product': ['Laptop', 'Phone', 'Tablet', 'Monitor', 'Keyboard'],
    'Prijs': [999, 699, 399, 299, 79],
    'Categorie': ['Computer', 'Mobile', 'Mobile', 'Computer', 'Computer'],
    'Voorraad': [15, 25, 30, 8, 50],
    'Rating': [4.5, 4.2, 4.0, 4.7, 4.1]
}

df = pd.DataFrame(data)

# Kolom selectie
print("Alleen productnamen:")
print(df['Product'])

print("\nMeerdere kolommen:")
print(df[['Product', 'Prijs']])

# Rij selectie met iloc (integer location)
print("\nEerste 3 rijen:")
print(df.iloc[:3])

# Rij selectie met loc (label-based)
print("\nRij met index 1:")
print(df.loc[1])

# Voorwaardelijke selectie
dure_producten = df[df['Prijs'] > 500]
print("\nProducten duurder dan €500:")
print(dure_producten)

# Meerdere voorwaarden
computer_duur = df[(df['Categorie'] == 'Computer') & (df['Prijs'] > 200)]
print("\nDure computer producten:")
print(computer_duur)

# Voorraad filter
weinig_voorraad = df[df['Voorraad'] < 20]
print("\nProducten met weinig voorraad:")
print(weinig_voorraad)

Data Cleaning en Transformatie

import pandas as pd
import numpy as np

# Sample data met missing values
data = {
    'Naam': ['Alice', 'Bob', None, 'Diana', 'Eva'],
    'Leeftijd': [25, 30, 35, np.nan, 32],
    'Email': ['[email protected]', '[email protected]', '[email protected]', None, '[email protected]'],
    'Salaris': [45000, 52000, np.nan, 51000, 49000]
}

df = pd.DataFrame(data)
print("Originele data:")
print(df)

# Missing values detecteren
print("\nMissing values per kolom:")
print(df.isnull().sum())

# Missing values verwijderen
df_dropped = df.dropna()
print("\nNa verwijderen missing values:")
print(df_dropped)

# Missing values opvullen
df_filled = df.copy()
df_filled['Naam'].fillna('Onbekend', inplace=True)
df_filled['Leeftijd'].fillna(df_filled['Leeftijd'].mean(), inplace=True)
df_filled['Salaris'].fillna(df_filled['Salaris'].median(), inplace=True)

print("\nNa opvullen missing values:")
print(df_filled)

# Nieuwe kolommen maken
df_filled['Salaris_K'] = df_filled['Salaris'] / 1000
df_filled['Leeftijd_Categorie'] = df_filled['Leeftijd'].apply(
    lambda x: 'Jong' if x < 30 else 'Oud'
)

print("\nMet nieuwe kolommen:")
print(df_filled)

Groepering en Aggregatie

import pandas as pd

# Sample sales data
sales_data = {
    'Datum': pd.date_range('2024-01-01', periods=20, freq='D'),
    'Product': ['Laptop', 'Phone', 'Tablet'] * 6 + ['Laptop', 'Phone'],
    'Verkoper': ['Alice', 'Bob', 'Charlie'] * 6 + ['Alice', 'Bob'],
    'Aantal': [2, 3, 1, 5, 2, 4, 1, 3, 2, 6, 3, 2, 4, 1, 5, 2, 3, 1, 4, 2],
    'Prijs_per_stuk': [999, 699, 399, 999, 699, 399, 999, 699, 399, 999, 
                       699, 399, 999, 699, 399, 999, 699, 399, 999, 699]
}

df = pd.DataFrame(sales_data)
df['Totaal_Verkoop'] = df['Aantal'] * df['Prijs_per_stuk']

print("Sales data:")
print(df.head(10))

# Groeperen per product
product_stats = df.groupby('Product').agg({
    'Aantal': ['sum', 'mean'],
    'Totaal_Verkoop': ['sum', 'mean', 'max']
}).round(2)

print("\nStatistieken per product:")
print(product_stats)

# Groeperen per verkoper
verkoper_stats = df.groupby('Verkoper')['Totaal_Verkoop'].sum().sort_values(ascending=False)
print("\nTotale verkoop per verkoper:")
print(verkoper_stats)

# Pivot tabel
pivot = df.pivot_table(
    values='Totaal_Verkoop',
    index='Product',
    columns='Verkoper',
    aggfunc='sum',
    fill_value=0
)
print("\nPivot tabel (Product vs Verkoper):")
print(pivot)

Praktisch Voorbeeld: Sales Analyse

Laten we alles samenvoegen in een praktisch voorbeeld waar we sales data analyseren:

import pandas as pd
import numpy as np
from datetime import datetime, timedelta

# Simuleren van realistische sales data
np.random.seed(42)
start_date = datetime(2024, 1, 1)
dates = [start_date + timedelta(days=i) for i in range(365)]

# Genereren van sales data
n_records = 1000
sales_data = {
    'Datum': np.random.choice(dates, n_records),
    'Product': np.random.choice(['Laptop', 'Phone', 'Tablet', 'Monitor', 'Keyboard'], n_records),
    'Verkoper': np.random.choice(['Alice', 'Bob', 'Charlie', 'Diana'], n_records),
    'Regio': np.random.choice(['Noord', 'Zuid', 'Oost', 'West'], n_records),
    'Aantal': np.random.randint(1, 10, n_records)
}

# Prijzen per product
prijzen = {'Laptop': 999, 'Phone': 699, 'Tablet': 399, 'Monitor': 299, 'Keyboard': 79}
sales_data['Prijs_per_stuk'] = [prijzen[product] for product in sales_data['Product']]

df = pd.DataFrame(sales_data)
df['Totaal_Verkoop'] = df['Aantal'] * df['Prijs_per_stuk']
df['Datum'] = pd.to_datetime(df['Datum'])

print("Sales Dataset:")
print(df.head())
print(f"\nDataset grootte: {df.shape}")

# Analyse 1: Top producten
print("\n=== TOP PRODUCTEN ===")
top_producten = df.groupby('Product')['Totaal_Verkoop'].sum().sort_values(ascending=False)
print(top_producten)

# Analyse 2: Beste verkopers
print("\n=== BESTE VERKOPERS ===")
top_verkopers = df.groupby('Verkoper').agg({
    'Totaal_Verkoop': 'sum',
    'Aantal': 'sum'
}).sort_values('Totaal_Verkoop', ascending=False)
print(top_verkopers)

# Analyse 3: Maandelijkse trends
print("\n=== MAANDELIJKSE VERKOPEN ===")
df['Maand'] = df['Datum'].dt.to_period('M')
maandelijkse_verkoop = df.groupby('Maand')['Totaal_Verkoop'].sum()
print(maandelijkse_verkoop.head(6))

# Analyse 4: Regionale prestaties
print("\n=== REGIONALE PRESTATIES ===")
regionale_stats = df.groupby('Regio').agg({
    'Totaal_Verkoop': ['sum', 'mean'],
    'Aantal': 'sum'
}).round(2)
print(regionale_stats)

# Analyse 5: Product mix per regio
print("\n=== PRODUCT MIX PER REGIO ===")
product_regio = df.pivot_table(
    values='Aantal',
    index='Product',
    columns='Regio',
    aggfunc='sum',
    fill_value=0
)
print(product_regio)

# Advanced: Top combinaties
print("\n=== TOP VERKOPER-PRODUCT COMBINATIES ===")
combinaties = df.groupby(['Verkoper', 'Product'])['Totaal_Verkoop'].sum().sort_values(ascending=False)
print(combinaties.head(10))

Data Visualisatie (Bonus)

Hoewel we in dit artikel focussen op NumPy en Pandas, is data visualisatie cruciaal voor data science. Hier is een snelle preview:

# Installeer eerst matplotlib: pip install matplotlib
import matplotlib.pyplot as plt

# Eenvoudige plot van maandelijkse verkopen
plt.figure(figsize=(12, 6))
maandelijkse_verkoop.plot(kind='line', marker='o')
plt.title('Maandelijkse Verkopen Trend')
plt.ylabel('Totale Verkoop (€)')
plt.xlabel('Maand')
plt.xticks(rotation=45)
plt.grid(True, alpha=0.3)
plt.tight_layout()
plt.show()

# Bar chart van top producten
plt.figure(figsize=(10, 6))
top_producten.plot(kind='bar', color=['#2563eb', '#10b981', '#7c3aed', '#f59e0b', '#ef4444'])
plt.title('Totale Verkoop per Product')
plt.ylabel('Totale Verkoop (€)')
plt.xlabel('Product')
plt.xticks(rotation=45)
plt.tight_layout()
plt.show()

Best Practices voor Data Science

  1. Data Quality First: Controleer altijd je data op missing values, duplicaten, en inconsistenties
  2. Exploratory Data Analysis (EDA): Begin altijd met het verkennen van je data
  3. Documenteer je werk: Gebruik duidelijke comments en markdown cells in Jupyter notebooks
  4. Reproduceerbare resultaten: Set random seeds voor consistente resultaten
  5. Performance optimalisatie: Gebruik vectorized operaties in plaats van loops
  6. Memory management: Let op memory usage bij grote datasets

Veelgemaakte Fouten

  • SettingWithCopyWarning: Gebruik .copy() bij het maken van views
  • Chained indexing: Vermijd df[condition][column] = value
  • Memory leaks: Sluit files en clear unused variables
  • Type conversions: Controleer data types na het inladen

Volgende Stappen

Nu je de fundamenten van NumPy en Pandas kent, kun je verder met:

  • Matplotlib/Seaborn: Data visualisatie
  • Scikit-learn: Machine learning
  • Jupyter Notebooks: Interactive development
  • SQL integration: Database connecties
  • Big Data tools: Dask, Spark voor grote datasets

Conclusie

NumPy en Pandas vormen de ruggengraat van data science in Python. Met NumPy krijg je krachtige numerieke berekeningen en met Pandas kun je complexe data manipulaties uitvoeren op een intuïtieve manier. De combinatie van beide libraries maakt Python tot de perfecte keuze voor data science projecten.

Het geheim van succesvol data science ligt in het begrijpen van je data en het stellen van de juiste vragen. Tools zijn belangrijk, maar domeinkennis en analytisch denken zijn essentieel.

Klaar om Data Scientist te worden?

In onze Data Science & Analytics cursus leer je niet alleen de tools, maar ook hoe je échte business problemen oplost met data. Van data cleaning tot machine learning - alles komt aan bod.

Meer informatie