Python w Data Science: NumPy, Pandas i Scikit-Learn w 2026
Praktyczny przewodnik po NumPy 2.1, Pandas 2.2 i Scikit-Learn 1.6 w Pythonie 3.12. Od czyszczenia danych przez inżynierię cech po kompletny pipeline ML — z pełnymi przykładami kodu.

Python pozostaje w 2026 roku niekwestionowanym liderem w dziedzinie data science. Trzy biblioteki odpowiadaja za ponad 90% codziennej pracy analitykow i inzynierow danych: NumPy zapewnia wydajne operacje numeryczne na tablicach wielowymiarowych, Pandas oferuje elastyczna manipulacje danymi tabelarycznymi, a Scikit-Learn dostarcza gotowe algorytmy uczenia maszynowego. Ten poradnik przeprowadza przez kazda z tych bibliotek na praktycznych przykladach, budujac kompletny pipeline, ktory wczytuje surowe dane, oczyszcza je, tworzy cechy i trenuje model klasyfikacyjny.
Wszystkie przyklady kodu dzialaja na Python 3.12+, NumPy 2.1, Pandas 2.2 oraz Scikit-Learn 1.6. Interfejsy API sa stabilne miedzy wersjami pomocniczymi, jednak optymalizacje wydajnosci w NumPy 2.x sprawiaja, ze aktualizacja jest oplacalna przy pracy z duzymi tablicami danych.
Operacje na tablicach NumPy: podstawy wydajnych obliczen
NumPy zastepuje standardowe listy Pythona tablicami n-wymiarowymi opartymi na ciaglych blokach pamieci. Roznica w wydajnosci jest znaczaca: zwektoryzowana operacja NumPy na milionie elementow dziala 50-100 razy szybciej niz rownowazna petla Pythona. Kazdy DataFrame w Pandas i kazdy model w Scikit-Learn wykorzystuje wewnetrznie tablice NumPy.
# numpy_basics.py
import numpy as np
# Create arrays from different sources
prices = np.array([29.99, 49.99, 19.99, 99.99, 39.99])
quantities = np.arange(1, 6) # [1, 2, 3, 4, 5]
# Vectorized arithmetic — no loops needed
revenue = prices * quantities
print(revenue) # [29.99, 99.98, 59.97, 399.96, 199.95]
# Statistical aggregations
print(f"Total revenue: ${revenue.sum():.2f}") # $789.85
print(f"Mean price: ${prices.mean():.2f}") # $47.99
print(f"Std deviation: ${prices.std():.2f}") # $27.64
# Boolean indexing — filter without loops
premium_mask = prices > 40
premium_items = prices[premium_mask] # [49.99, 99.99]Indeksowanie logiczne (boolean indexing) to wzorzec najczesciej spotykany w praktycznym kodzie data science. Zamiast pisac instrukcje if wewnatrz petli, maska logiczna wybiera elementy spelniajace warunek w ramach jednej operacji. Wyrazenie prices > 40 tworzy tablice wartosci True/False, ktora sluzy bezposrednio jako filtr — ten sam mechanizm jest wykorzystywany w Pandas, poniewaz biblioteka ta bazuje wewnetrznie na NumPy.
Reshaping i broadcasting w NumPy
Operacje na danych wielowymiarowych wymagaja zrozumienia mechanizmu broadcastingu, czyli sposobu, w jaki NumPy przeprowadza operacje na tablicach o roznych ksztaltach. Reguly broadcastingu pozwalaja na wykonywanie dzialan miedzy macierza a wektorem bez jawnego powielania danych.
# numpy_reshape.py
import numpy as np
# Monthly sales data: 4 products x 3 months
sales = np.array([
[120, 150, 130], # Product A
[200, 180, 220], # Product B
[90, 110, 95], # Product C
[300, 280, 310], # Product D
])
# Column-wise mean (average per month)
monthly_avg = sales.mean(axis=0) # [177.5, 180.0, 188.75]
# Row-wise sum (total per product)
product_totals = sales.sum(axis=1) # [400, 600, 295, 890]
# Normalize each product relative to its own max
normalized = sales / sales.max(axis=1, keepdims=True)
# keepdims=True preserves the shape for broadcasting
print(normalized[0]) # [0.8, 1.0, 0.867] — Product A relative to its peak
# Reshape for Scikit-Learn (requires 2D input)
flat_sales = sales.flatten() # 1D array of 12 values
reshaped = flat_sales.reshape(-1, 1) # 12x1 column vectorParametr axis kontroluje kierunek agregacji: axis=0 zwija wiersze (operuje kolumnowo), axis=1 zwija kolumny (operuje wierszowo). Argument keepdims=True zapobiega problemom z ksztaltem tablicy podczas broadcastingu — zachowuje wymiar (4, 1), co umozliwia poprawne dzielenie macierzy przez wektor maksimow. Operacja reshape(-1, 1) na koncu to czesto spotykany wzorzec: Scikit-Learn wymaga danych wejsciowych w formacie co najmniej dwuwymiarowym.
Manipulacja i czyszczenie danych w Pandas DataFrame
Pandas opakowuje tablice NumPy etykietowanymi osiami i operacjami przypominajacymi SQL. DataFrame to centralna struktura danych — tabela, w ktorej kazda kolumna moze przechowywac inny typ danych. Pandas 2.2 domyslnie uzywa kolumn tekstowych opartych na PyArrow, co znaczaco zmniejsza zuzycie pamieci w porownaniu z kolumnami typu object.
# pandas_cleaning.py
import pandas as pd
import numpy as np
# Load and inspect raw data
df = pd.read_csv("candidates.csv")
print(df.shape) # (1500, 8)
print(df.dtypes) # Check column types
print(df.isna().sum()) # Count missing values per column
# Clean in a reproducible chain
df_clean = (
df
.dropna(subset=["salary", "experience_years"]) # Drop rows missing critical fields
.assign(
salary=lambda x: x["salary"].clip(lower=20000, upper=500000), # Cap outliers
experience_years=lambda x: x["experience_years"].astype(int),
hired_date=lambda x: pd.to_datetime(x["hired_date"], errors="coerce"),
)
.drop_duplicates(subset=["email"]) # Remove duplicate candidates
.query("experience_years >= 0") # Filter invalid entries
.reset_index(drop=True)
)
print(f"Cleaned: {len(df)} -> {len(df_clean)} rows")Lancuchowanie metod z uzyciem .assign() sprawia, ze transformacje pozostaja czytelne i odtwarzalne. Kazdy krok dokumentuje dokladnie, co ulega zmianie i dlaczego. Wzorzec lambda x: wewnatrz .assign() odwoluje sie do DataFrame w stanie, w jakim istnieje w danym punkcie lancucha, co eliminuje ryzyko odwolan do nieaktualnych danych. Metoda clip() ogranicza wartosci wynagrodzen do realistycznego zakresu, zapobiegajac znieksztalceniu modelu przez wartosci odstajace.
Pandas 2.2 domyslnie wlacza mechanizm Copy-on-Write. Eliminuje to ostrzezenie SettingWithCopyWarning i sprawia, ze operacje lancuchowe sa bezpieczniejsze. Modyfikacje wycinka (slice) nie mutuja juz po cichu oryginalnego DataFrame — Pandas tworzy kopie dopiero wtedy, gdy faktycznie dochodzi do zapisu danych.
Agregacje GroupBy i inzynieria cech w Pandas
Operacja GroupBy dzieli dane na podzbiory, stosuje funkcje do kazdego podzbioru i laczy wyniki. Ten wzorzec napedza wiekszosc procesow inzynierii cech w tabelarycznym uczeniu maszynowym. Odpowiednio zaprojektowane cechy — takie jak stosunek indywidualnego wynagrodzenia do sredniej w dziale — czesto maja wiekszy wplyw na jakosc modelu niz wybor algorytmu.
# pandas_groupby.py
import pandas as pd
# Aggregate candidate stats by department
dept_stats = (
df_clean
.groupby("department")
.agg(
avg_salary=("salary", "mean"),
median_experience=("experience_years", "median"),
headcount=("email", "count"),
max_salary=("salary", "max"),
)
.sort_values("avg_salary", ascending=False)
)
print(dept_stats.head())
# Create features for ML: encode categorical + add aggregated stats
df_features = (
df_clean
.assign(
# Ratio of individual salary to department average
salary_ratio=lambda x: x["salary"] / x.groupby("department")["salary"].transform("mean"),
# Time since hire in days
tenure_days=lambda x: (pd.Timestamp.now() - x["hired_date"]).dt.days,
# Binary encoding
is_senior=lambda x: (x["experience_years"] >= 5).astype(int),
)
)Metoda .transform() zwraca Series wyrownana z oryginalnym indeksem, co pozwala bezpiecznie uzywac jej wewnatrz .assign(). Unika sie w ten sposob czestego bledu polegajacego na recznym dolaczaniu zagregowanych wynikow z powrotem do oryginalnego DataFrame. Cecha salary_ratio mowi modelowi, jak wynagrodzenie danej osoby ma sie do sredniej w jej dziale, a tenure_days przeksztalca date w wartosc numeryczna, ktora algorytm moze bezposrednio przetworzyc.
Gotowy na rozmowy o Data Science & ML?
Ćwicz z naszymi interaktywnymi symulatorami, flashcards i testami technicznymi.
Budowa pipeline Scikit-Learn od podstaw
Pipeline w Scikit-Learn lacza kroki preprocessingu i model w jeden obiekt. Taka konstrukcja zapobiega wyciekowi danych (data leakage), poniewaz transformery sa dopasowywane wylacznie na danych treningowych, a nastepnie te same transformacje sa stosowane do danych testowych.
# sklearn_pipeline.py
from sklearn.model_selection import train_test_split
from sklearn.pipeline import Pipeline
from sklearn.compose import ColumnTransformer
from sklearn.preprocessing import StandardScaler, OneHotEncoder
from sklearn.ensemble import GradientBoostingClassifier
from sklearn.metrics import classification_report
import pandas as pd
# Define column groups
numeric_features = ["salary", "experience_years", "salary_ratio", "tenure_days"]
categorical_features = ["department", "role_level"]
target = "promoted"
# Split before any preprocessing
X = df_features[numeric_features + categorical_features]
y = df_features[target]
X_train, X_test, y_train, y_test = train_test_split(
X, y, test_size=0.2, random_state=42, stratify=y
)
# Build the preprocessing + model pipeline
preprocessor = ColumnTransformer(
transformers=[
("num", StandardScaler(), numeric_features), # Scale numeric columns
("cat", OneHotEncoder(handle_unknown="ignore"), categorical_features), # Encode categories
]
)
pipeline = Pipeline([
("preprocessor", preprocessor),
("classifier", GradientBoostingClassifier(
n_estimators=200,
learning_rate=0.1,
max_depth=4,
random_state=42,
)),
])
# Train and evaluate
pipeline.fit(X_train, y_train)
y_pred = pipeline.predict(X_test)
print(classification_report(y_test, y_pred))ColumnTransformer stosuje rozne etapy preprocessingu do roznych typow kolumn w jednym kroku. StandardScaler normalizuje cechy numeryczne do sredniej rownej zero i wariancji rownej jeden. OneHotEncoder konwertuje lancuchy kategoryczne na kolumny binarne. Parametr handle_unknown="ignore" gwarantuje, ze pipeline nie ulegnie awarii, jesli dane testowe zawieraja kategorie nieobecne w zbiorze treningowym.
Walidacja krzyzowa i strojenie hiperparametrow
Pojedynczy podzial na zbior treningowy i testowy moze dawac mylace wyniki w zaleznosci od tego, ktore probki trafia do kazdego zbioru. Walidacja krzyzowa przeprowadza wiele podzialow i usrednia wyniki, co daje bardziej wiarygodna ocene wydajnosci modelu.
# sklearn_tuning.py
from sklearn.model_selection import cross_val_score, GridSearchCV
import numpy as np
# 5-fold cross-validation on the full pipeline
scores = cross_val_score(pipeline, X_train, y_train, cv=5, scoring="f1")
print(f"F1 scores: {scores}")
print(f"Mean F1: {scores.mean():.3f} (+/- {scores.std() * 2:.3f})")
# Grid search over hyperparameters
param_grid = {
"classifier__n_estimators": [100, 200, 300],
"classifier__max_depth": [3, 4, 5],
"classifier__learning_rate": [0.05, 0.1, 0.2],
}
grid_search = GridSearchCV(
pipeline,
param_grid,
cv=5,
scoring="f1",
n_jobs=-1, # Use all CPU cores
verbose=1,
)
grid_search.fit(X_train, y_train)
print(f"Best params: {grid_search.best_params_}")
print(f"Best F1: {grid_search.best_score_:.3f}")
# Evaluate the best model on held-out test set
best_model = grid_search.best_estimator_
print(classification_report(y_test, best_model.predict(X_test)))Skladnia z podwojnym podkreslnikiem (classifier__max_depth) odwoluje sie do zagniezdonych parametrow wewnatrz pipeline. n_jobs=-1 zrownolegla przeszukiwanie na wszystkich dostepnych rdzeniach procesora, co moze skrocic czas strojenia z godzin do minut na maszynach wielordzeniowych. Przy siatce 3x3x3 kombinacji i 5-krotnej walidacji krzyzowej trenowanych jest lacznie 135 modeli.
Dopasowanie skalera na calym zbiorze danych przed podzialem powoduje wyciek informacji z foldow walidacyjnych do foldow treningowych. Umieszczenie skalera wewnatrz Pipeline gwarantuje, ze skalowanie jest dopasowywane wylacznie na czesci treningowej kazdego foldu. To najczesciej popelniany blad w pytaniach rekrutacyjnych dotyczacych uczenia maszynowego.
Zapis i wczytywanie modeli do produkcji
Wytrenowany pipeline musi zostac zserializowany na potrzeby wdrozenia. Biblioteka joblib obsluguje tablice NumPy wydajniej niz wbudowany modul pickle w Pythonie, co ma znaczenie przy duzych modelach z wieloma parametrami.
# sklearn_export.py
import joblib
from pathlib import Path
# Save the complete pipeline (preprocessor + model)
model_dir = Path("models")
model_dir.mkdir(exist_ok=True)
joblib.dump(best_model, model_dir / "promotion_model_v1.joblib")
# Load and predict in a different process
loaded_model = joblib.load(model_dir / "promotion_model_v1.joblib")
new_data = pd.DataFrame({
"salary": [75000],
"experience_years": [4],
"salary_ratio": [1.05],
"tenure_days": [730],
"department": ["Engineering"],
"role_level": ["Mid"],
})
prediction = loaded_model.predict(new_data)
probability = loaded_model.predict_proba(new_data)[:, 1]
print(f"Promoted: {bool(prediction[0])}, Confidence: {probability[0]:.2%}")Zapisywanie calego pipeline zamiast samego modelu gwarantuje, ze kroki preprocessingu zostana zastosowane identycznie podczas inferencji. Plik .joblib zawiera wszystkie parametry skalera i slowniki enkodera — przy wczytywaniu w innym procesie nie trzeba ponownie przetwarzac danych treningowych. Metoda predict_proba() zwraca prawdopodobienstwa klas, a slice [:, 1] ekstrahuje prawdopodobienstwo klasy pozytywnej, co w praktyce jest bardziej informatywne niz sama predykcja binarna.
Podsumowanie
- NumPy dostarcza fundamenty: wydajne tablice n-wymiarowe, operacje wektorowe i boolean indexing, ktore eliminuja wolne petle Pythona.
- Pandas rozbudowuje te fundamenty o etykietowane osie, operacje SQL-owe, lancuchowanie metod i mechanizm GroupBy niezbedny do inzynierii cech.
- Scikit-Learn zamyka cykl pracy: pipeline lacza preprocessing z modelem, walidacja krzyzowa daje wiarygodna ocene jakosci, a
GridSearchCVautomatyzuje strojenie hiperparametrow. - Umieszczenie skalera wewnatrz pipeline to kluczowa praktyka zapobiegajaca wyciekowi danych — najczestszemu bledowi w projektach ML i na rozmowach kwalifikacyjnych.
- Serializacja calego pipeline za pomoca
joblibzapewnia, ze preprocessing i model sa zawsze zsynchronizowane przy wdrazaniu do produkcji. - Opanowanie tych trzech bibliotek otwiera droge do bardziej zaawansowanych frameworkow, takich jak PyTorch czy XGBoost, ktorych konwencje API opieraja sie na tych samych zasadach. Wiecej materialow do nauki i cwiczen mozna znalezc na stronie technologii data science.
Zacznij ćwiczyć!
Sprawdź swoją wiedzę z naszymi symulatorami rozmów i testami technicznymi.
Tagi
Udostępnij
Powiązane artykuły

Algorytmy uczenia maszynowego: kompletny przewodnik po rozmowach technicznych
Opanowanie kluczowych algorytmów uczenia maszynowego wymaganych na rozmowach technicznych w 2026 roku. Uczenie nadzorowane i nienadzorowane, metody zespolowe, metryki ewaluacji i regularyzacja z implementacjami w Pythonie.

Top 25 pytań rekrutacyjnych z Data Science w 2026 roku
Kompleksowy przegląd 25 najczęstszych pytań na rozmowach kwalifikacyjnych dla data scientistów w 2026 roku — od statystyki i ML po SQL, inżynierię cech i architekturę transformerów.