# 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. - Published: 2026-04-07 - Updated: 2026-04-07 - Author: Anthony Fillion-Maillet - Tags: data-science, python, numpy, pandas, scikit-learn, machine-learning, tutorial - Reading time: 10 min --- 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. > **Wersje uzyte w tym poradniku** > > 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. ```python # 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. ```python # 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 vector ``` Parametr `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`. ```python # 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: Copy-on-Write** > > 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. ```python # 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. ## 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. ```python # 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. ```python # 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. > **Wyciek danych w walidacji krzyzowej** > > 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. ```python # 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 `GridSearchCV` automatyzuje 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 `joblib` zapewnia, 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](/technologies/data-science). --- Source: SharpSkill (https://sharpskill.dev), tech interview preparation for your real stack. HTML version of this page: https://sharpskill.dev/pl/blog/data-science/python-data-science-numpy-pandas-scikit-learn-2026