Quiz 2

Pandas for Deep Learning: DataFrames, Series, and GPU-Accelerated Data Processing

1284 words
6 min read
Python Week 1: the first filter for runtime behavior
Visual companion
Python
Type and operator map

Python Week 1: the first filter for runtime behavior

View
Revision summary

What this note is really saying

Short form

# Pandas for Deep Learning: DataFrames, Series, and GPU-Accelerated Data Processing ## 🎯 Learning Objectives - Use Pandas DataFrames and Series for efficient data manipulation - Perform groupby, apply, and aggregation operations for feature engineering - Integrate Pandas with PyTorch/TensorFlow data pipelines - Use...

Pandas for Deep Learning: DataFrames, Series, and GPU-Accelerated Data Processing

🎯 Learning Objectives

  • Use Pandas DataFrames and Series for efficient data manipulation
  • Perform groupby, apply, and aggregation operations for feature engineering
  • Integrate Pandas with PyTorch/TensorFlow data pipelines
  • Use GPU-accelerated data processing (cuDF) for large datasets
  • Work with sklearn's dataset API for quick prototyping

📋 Prerequisites

  • Python basics: Lists, dictionaries, functions
  • PyTorch basics (Week 1): Tensor operations
  • Data Pipelines (Week 2): Dataset and DataLoader concepts

1. 📖 Core Content

1.1 Intuition: Why Pandas for DL?

Raw data is rarely ready for deep learning. You need to:
  1. Load CSV/JSON/Parquet files
  2. Clean missing values
  3. Encode categorical features
  4. Normalize numerical features
  5. Create train/val/test splits
  6. Convert to PyTorch tensors Pandas is the swiss army knife for all of this. It handles 90% of data preprocessing tasks with concise, readable code.

1.2 Pandas Fundamentals for DL

1.2.1 Loading Data

python
# runnable
import pandas as pd
import numpy as np
# From CSV
df = pd.read_csv('data.csv')
# From Parquet (faster for large datasets)
df = pd.read_parquet('data.parquet')
# From SQL
import sqlite3
conn = sqlite3.connect('database.db')
df = pd.read_sql('SELECT * FROM images', conn)
# Quick check
print(df.shape)         # (rows, columns)
print(df.head())        # First 5 rows
print(df.info())        # Types, non-null counts
print(df.describe())    # Summary statistics

1.2.2 Handling Missing Data

python
# runnable
import pandas as pd
import numpy as np
df = pd.DataFrame({
    'age': [25, 30, np.nan, 35, 28],
    'income': [50000, 60000, 75000, np.nan, 55000],
    'label': [0, 1, 0, 1, np.nan]
})
# Check missing values
print(df.isnull().sum())
# Fill strategies for ML
# For numerical features: median (robust to outliers)
df['age'] = df['age'].fillna(df['age'].median())
df['income'] = df['income'].fillna(df['income'].median())
# For categorical features: mode
# For label: drop rows with missing labels (can't train on them)
df = df.dropna(subset=['label'])
print(df)

1.2.3 Categorical Encoding

python
# runnable
import pandas as pd
from sklearn.preprocessing import LabelEncoder, OneHotEncoder
df = pd.DataFrame({
    'city': ['NYC', 'LA', 'SF', 'NYC', 'LA'],
    'price': [100, 200, 150, 120, 180]
})
# Label encoding (for ordinal categories)
le = LabelEncoder()
df['city_label'] = le.fit_transform(df['city'])
print("Label encoded:", df'city', 'city_label'.drop_duplicates())
# One-hot encoding (for nominal categories)
df_onehot = pd.get_dummies(df, columns=['city'], prefix='city')
print("\nOne-hot encoded:", df_onehot)

1.3 Groupby and Aggregation for Feature Engineering

python
# runnable
import pandas as pd
import numpy as np
# Transaction data: compute user-level features
transactions = pd.DataFrame({
    'user_id': [1, 1, 1, 2, 2, 3],
    'amount': [100, 200, 50, 300, 150, 500],
    'category': ['food', 'travel', 'food', 'travel', 'food', 'travel'],
    'timestamp': pd.date_range('2024-01-01', periods=6, freq='D')
})
# User-level aggregate features
user_features = transactions.groupby('user_id').agg({
    'amount': ['sum', 'mean', 'std', 'count'],
    'category': lambda x: x.nunique()
}).reset_index()
# Flatten column names
user_features.columns = ['user_id', 'total_spend', 'avg_spend',
                         'std_spend', 'txn_count', 'unique_categories']
print(user_features)

1.4 Pandas + PyTorch Integration

python
# runnable
import pandas as pd
import torch
from torch.utils.data import Dataset
class PandasDataset(Dataset):
    def __init__(self, df: pd.DataFrame, feature_cols, label_col):
        self.features = torch.tensor(df[feature_cols].values, dtype=torch.float32)
        self.labels = torch.tensor(df[label_col].values, dtype=torch.float32)
    def __len__(self):
        return len(self.features)
    def __getitem__(self, idx):
        return self.features[idx], self.labels[idx]
# Example usage
df = pd.DataFrame({
    'feature_1': np.random.randn(1000),
    'feature_2': np.random.randn(1000),
    'label': np.random.randint(0, 2, 1000)
})
dataset = PandasDataset(df, ['feature_1', 'feature_2'], 'label')
dataloader = torch.utils.data.DataLoader(dataset, batch_size=32, shuffle=True)
for batch_x, batch_y in dataloader:
    print(f"Batch: X shape {batch_x.shape}, y shape {batch_y.shape}")
    break

1.5 GPU-Accelerated Pandas with cuDF

For datasets too large for Pandas (10M+ rows), use cuDF (RAPIDS GPU DataFrame):
python
# runnable
# Note: cuDF requires NVIDIA GPU with RAPIDS installed
# import cudf
#
# gpu_df = cudf.read_csv('large_dataset.csv')
# gpu_df['features'] = gpu_df.groupby('user_id')['amount'].transform('mean')
# gpu_tensor = torch.as_tensor(gpu_df.to_cupy())  # Zero-copy to PyTorch
# CPU fallback for this example:
print("For >10M rows, use cuDF for 10-50x speedup over Pandas")

1.6 Worked Example: End-to-End Data Pipeline

python
# runnable
import pandas as pd
import numpy as np
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
import torch
# Step 1: Create synthetic data
np.random.seed(42)
n_samples = 10000
df = pd.DataFrame({
    'age': np.random.randint(18, 80, n_samples),
    'income': np.random.lognormal(mean=10, sigma=1, size=n_samples),
    'education_level': np.random.choice(['HS', 'BS', 'MS', 'PhD'], n_samples),
    'city': np.random.choice(['NYC', 'LA', 'SF', 'CHI'], n_samples),
    'target': np.random.randint(0, 2, n_samples)
})
print(f"Original shape: {df.shape}")
print(df.head())
# Step 2: Handle missing values (none in this synthetic data)
# Step 3: Encode categorical features
df = pd.get_dummies(df, columns=['education_level', 'city'], drop_first=True)
# Step 4: Split features and target
X = df.drop('target', axis=1)
y = df['target']
# Step 5: Train/val/test split
X_train, X_temp, y_train, y_temp = train_test_split(X, y, test_size=0.3, random_state=42)
X_val, X_test, y_val, y_test = train_test_split(X_temp, y_temp, test_size=0.5, random_state=42)
print(f"Train: {X_train.shape}, Val: {X_val.shape}, Test: {X_test.shape}")
# Step 6: Normalize numerical features
scaler = StandardScaler()
X_train_scaled = scaler.fit_transform(X_train)
X_val_scaled = scaler.transform(X_val)
X_test_scaled = scaler.transform(X_test)
# Step 7: Convert to PyTorch tensors
train_dataset = torch.utils.data.TensorDataset(
    torch.tensor(X_train_scaled, dtype=torch.float32),
    torch.tensor(y_train.values, dtype=torch.float32)
)
train_loader = torch.utils.data.DataLoader(train_dataset, batch_size=64, shuffle=True)
print(f"Ready for training: {len(train_loader)} batches per epoch")

1.7 Why This Matters

Pandas handles the "last mile" of data preprocessing for deep learning. While DL models learn representations, they still need clean, normalized input data. Mastering Pandas operations for DL means:
  • Faster prototyping (no waiting for ETL pipelines)
  • Reproducible preprocessing (code, not manual steps)
  • Integration with any deep learning framework

2. 📐 Key Formulas / Concepts

OperationPandas CodeDL Use
Load CSVpd.read_csv('file.csv')Load training data
Handle NaNdf.fillna(df.median())Missing value imputation
One-hot encodepd.get_dummies(df['col'])Categorical features
Groupby aggdf.groupby('key').agg({'val': 'mean'})Feature engineering
Train/test splitsklearn.model_selection.train_test_splitDataset splitting
NormalizeStandardScaler().fit_transform(df)Feature scaling

3. ⚠️ Common Pitfalls

Pitfall 1: Data Leakage Through Improper Split

Mistake: Fitting the scaler on the entire dataset before splitting. Why: The scaler "sees" the test data statistics, leaking information. The test set is no longer an unbiased estimate of generalization. Correct approach: Fit scaler on training data only, then transform validation and test sets.

Pitfall 2: Not Handling Categorical Variables

Mistake: Feeding string columns directly to PyTorch. Why: PyTorch tensors require numerical values. String columns raise TypeError. Correct approach: Use pd.get_dummies() or LabelEncoder for all categorical columns before creating tensors.

Pitfall 3: Using Pandas for GPU Training Data Loading

Mistake: Converting entire dataset to Pandas DataFrame, then to PyTorch tensor, causing CPU-GPU data transfer bottleneck. Correct approach: For large datasets, use GPU-accelerated loading (cuDF, NVIDIA DALI, or PyTorch's DataLoader with num_workers).

4. 📝 Practice Questions

Q1: Load a CSV with columns [age, income, city, purchased]. Handle missing ages by filling with median. One-hot encode city. Split 70/15/15. Write the full pipeline.
python
import pandas as pd
import numpy as np
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler

# Load
df = pd.read_csv('data.csv')

# Handle missing
df['age'] = df['age'].fillna(df['age'].median())

# One-hot encode
df = pd.get_dummies(df, columns=['city'], drop_first=True)

# Split
X = df.drop('purchased', axis=1)
y = df['purchased']

X_train, X_temp, y_train, y_temp = train_test_split(X, y, test_size=0.3, random_state=42)
X_val, X_test, y_val, y_test = train_test_split(X_temp, y_temp, test_size=0.5, random_state=42)

# Scale
scaler = StandardScaler()
X_train = scaler.fit_transform(X_train)
X_val = scaler.transform(X_val)
X_test = scaler.transform(X_test)
Q2: You have transaction data (user_id, amount, timestamp). Create features: total amount in last 7 days, transaction count in last 7 days, days since last transaction.
python
import pandas as pd

df = pd.read_csv('transactions.csv')
df['timestamp'] = pd.to_datetime(df['timestamp'])
df = df.sort_values(['user_id', 'timestamp'])

# Window features (last 7 days per row)
def compute_window_features(group):
    group = group.sort_values('timestamp')
    group['total_7d'] = group['amount'].rolling('7D', on='timestamp').sum()
    group['count_7d'] = group['amount'].rolling('7D', on='timestamp').count()
    group['days_since_last'] = group['timestamp'].diff().dt.days.fillna(999)
    return group

df = df.groupby('user_id').apply(compute_window_features)

5. 🔗 Cross-References

Document outline

Keep your place and jump directly to a heading.

Table of Contents
System Normal // Awaiting Context

Intelligence Hub

Navigate the knowledge graph to generate context. The Hub adapts dynamically to surface backlinks, related notes, and metadata insights.