Back to Tracker

Python for AI

Python · NumPy · Pandas · Matplotlib · Scikit-learn

Foundation Module 1.5 Weeks 5 Lessons Prepflix AI Roadmap
Python Essentials for ML

List Comprehensions

# squares of even numbers sq = [x**2 for x in range(10) if x % 2 == 0] # dict comprehension label_map = {k: i for i, k in enumerate(classes)}

Lambda & Functional

normalize = lambda x: (x - x.min()) / (x.max() - x.min()) result = list(map(lambda x: x**2, data)) filtered = list(filter(lambda x: x > 0, data))

Classes for ML

class LinearModel: def __init__(self, lr=0.01): self.lr = lr self.w = None def fit(self, X, y): self.w = np.zeros(X.shape[1]) for _ in range(1000): pred = X @ self.w grad = X.T @ (pred - y) / len(y) self.w -= self.lr * grad def predict(self, X): return X @ self.w
Best Practice: Always write ML models as classes with fit() and predict() methods — this follows scikit-learn's API and makes your code composable in pipelines.
NumPy: Arrays & Broadcasting

Essential Operations

import numpy as np # Creation a = np.array([1,2,3]) X = np.zeros((100,10)) # 100×10 matrix of zeros X = np.random.randn(100,10) # standard normal init I = np.eye(5) # 5×5 identity matrix # Shape manipulation X.reshape(-1, 1) # column vector X.T # transpose np.concatenate([A, B], axis=1) # horizontal stack np.vstack([A, B]) # vertical stack # Math ops (vectorized, no for-loops!) dot = A @ B # matrix multiply norm = np.linalg.norm(v) # L2 norm eig = np.linalg.eig(A) # eigendecomposition inv = np.linalg.inv(A) # matrix inverse # Broadcasting example X = np.random.randn(1000, 10) # 1000 samples, 10 features mu = X.mean(axis=0) # shape (10,) X_centered = X - mu # broadcasts across 1000 rows!

Indexing & Slicing

X[0] # first row X[:, 2] # third column X[5:10, :3] # rows 5-9, cols 0-2 X[mask] # boolean indexing X[[0,3,7]] # fancy indexing

Performance Tips

  • Avoid Python for-loops — use vectorized ops
  • np.dot calls BLAS (10-100× faster)
  • Use float32 for GPU: saves memory
  • np.einsum for complex tensor ops
  • Profile with %timeit in Jupyter
Pandas: Data Wrangling
import pandas as pd df = pd.read_csv('data.csv') # Exploration df.head(); df.info(); df.describe() df.isnull().sum() # missing values per column df.value_counts('label') # class distribution # Filtering & Selection df[df['age'] > 25] # boolean filter df[['name', 'salary']] # select columns df.loc[0:5, 'age':'salary'] # label-based df.iloc[0:5, 2:5] # position-based # Cleaning df.dropna(subset=['salary']) # drop rows with NaN in salary df['age'].fillna(df['age'].median(), inplace=True) df.drop_duplicates(inplace=True) # Feature Engineering df['age_bucket'] = pd.cut(df['age'], bins=[0,18,35,60,100]) df['log_salary'] = np.log1p(df['salary']) # GroupBy (most common in interviews!) agg = df.groupby('dept').agg({'salary': ['mean','std','count']}) pivot = df.pivot_table(values='revenue', index='region', columns='quarter', aggfunc='sum') # Merging merged = pd.merge(df1, df2, on='user_id', how='left')
Interview Pattern: Most data science interviews test GroupBy + Merge. Practice: "find the department with highest average salary for employees hired after 2020."
Visualization: Matplotlib & Seaborn
import matplotlib.pyplot as plt import seaborn as sns # Training loss curve fig, axes = plt.subplots(1, 2, figsize=(12, 4)) axes[0].plot(train_losses, label='Train', color='#0d6efd') axes[0].plot(val_losses, label='Val', color='#dc3545', linestyle='--') axes[0].set_title('Loss Curve'); axes[0].legend() # Confusion matrix sns.heatmap(cm, annot=True, fmt='d', cmap='Blues', ax=axes[1]) axes[1].set_title('Confusion Matrix') plt.tight_layout() plt.savefig('results.png', dpi=150, bbox_inches='tight') # Distribution analysis sns.histplot(df['salary'], kde=True, bins=30) sns.boxplot(x='dept', y='salary', data=df) sns.heatmap(df.corr(), annot=True, cmap='coolwarm')
Scikit-learn: Pipelines & APIs
from sklearn.pipeline import Pipeline from sklearn.preprocessing import StandardScaler, OneHotEncoder from sklearn.compose import ColumnTransformer from sklearn.ensemble import RandomForestClassifier from sklearn.model_selection import cross_val_score, GridSearchCV from sklearn.metrics import classification_report, roc_auc_score # Build preprocessing pipeline num_pipe = Pipeline([('scaler', StandardScaler())]) cat_pipe = Pipeline([('ohe', OneHotEncoder(handle_unknown='ignore'))]) preprocessor = ColumnTransformer([ ('num', num_pipe, num_features), ('cat', cat_pipe, cat_features) ]) # Full pipeline with model pipe = Pipeline([ ('prep', preprocessor), ('clf', RandomForestClassifier(n_estimators=200, random_state=42)) ]) # Cross-validation scores = cross_val_score(pipe, X_train, y_train, cv=5, scoring='roc_auc') print(f"AUC: {scores.mean():.3f} ± {scores.std():.3f}") # Hyperparameter tuning params = {'clf__n_estimators': [100,200], 'clf__max_depth': [None,10,20]} gs = GridSearchCV(pipe, params, cv=5, scoring='roc_auc', n_jobs=-1) gs.fit(X_train, y_train) print(gs.best_params_) # Evaluation y_pred = gs.predict(X_test) print(classification_report(y_test, y_pred)) print(f"Test AUC: {roc_auc_score(y_test, gs.predict_proba(X_test)[:,1]):.3f}")
Always use Pipelines — they prevent data leakage (fitting the scaler on test data), make deployment easy (one pipe.predict() call), and let you tune preprocessing hyperparameters alongside model hyperparameters.