Day 103 — Pandas 进阶:图解
1. 数据清洗流程
┌─────────────────────────────────────────────────┐
│ 原始数据(脏数据) │
├─────────────────────────────────────────────────┤
│ • 缺失值 (NaN/None) │
│ • 重复行 │
│ • 错误数据类型 │
│ • 异常值 (离群点) │
│ • 格式不一致 │
└───────────────────────┬─────────────────────────┘
↓
┌─────────────────────────────────────────────────┐
│ Step 1: 缺失值处理 │
│ ┌───────────────────────────────────────┐ │
│ │ 删除: df.dropna() │ │
│ │ 填充: df.fillna(0) │ │
│ │ 插值: df.interpolate() │ │
│ └───────────────────────────────────────┘ │
└───────────────────────┬─────────────────────────┘
↓
┌─────────────────────────────────────────────────┐
│ Step 2: 重复值处理 │
│ ┌───────────────────────────────────────┐ │
│ │ 检测: df.duplicated() │ │
│ │ 删除: df.drop_duplicates() │ │
│ └───────────────────────────────────────┘ │
└───────────────────────┬─────────────────────────┘
↓
┌─────────────────────────────────────────────────┐
│ Step 3: 数据类型转换 │
│ ┌───────────────────────────────────────┐ │
│ │ 转数值: pd.to_numeric() │ │
│ │ 转日期: pd.to_datetime() │ │
│ │ 转类别: astype('category') │ │
│ └───────────────────────────────────────┘ │
└───────────────────────┬─────────────────────────┘
↓
┌─────────────────────────────────────────────────┐
│ Step 4: 异常值处理 │
│ ┌───────────────────────────────────────┐ │
│ │ IQR 法: Q1-1.5*IQR ~ Q3+1.5*IQR │ │
│ │ Z-score: |z| > 3 │ │
│ │ 截断: df.clip(lower, upper) │ │
│ └───────────────────────────────────────┘ │
└───────────────────────┬─────────────────────────┘
↓
┌─────────────────────────────────────────────────┐
│ 清洗后数据(干净数据) │
└─────────────────────────────────────────────────┘
2. merge 连接类型
内连接 (inner): 保留两表都有的行
┌─────────┐ ┌─────────┐
│ 表 A │ │ 表 B │
│ ┌─────┐ │ │ ┌─────┐ │
│ │ A∩B │ ←───→ │ │ A∩B │ │
│ └─────┘ │ │ └─────┘ │
└─────────┘ └─────────┘
左连接 (left): 保留左表所有行
┌─────────┐ ┌─────────┐
│ 表 A │ │ 表 B │
│ ┌─────┐ │ │ ┌─────┐ │
│ │ A │ │ │ │ A∩B │ │
│ │ │ │ │ └─────┘ │
│ │ A∩B │ │ └─────────┘
│ └─────┘ │
└─────────┘
右连接 (right): 保留右表所有行
┌─────────┐ ┌─────────┐
│ 表 A │ │ 表 B │
│ ┌─────┐ │ │ ┌─────┐ │
│ │ A∩B │ │ │ │ B │ │
│ └─────┘ │ │ │ │ │
└─────────┘ │ │ A∩B │ │
│ └─────┘ │
└─────────┘
外连接 (outer): 保留所有行
┌─────────┐ ┌─────────┐
│ 表 A │ │ 表 B │
│ ┌─────┐ │ │ ┌─────┐ │
│ │ A │ │ │ │ B │ │
│ │ A∩B │←─────→│ │ A∩B │ │
│ └─────┘ │ │ └─────┘ │
└─────────┘ └─────────┘
3. groupby 工作流程
原始 DataFrame:
┌────┬───────┬──────┐
│ │ 部门 │ 薪资 │
├────┼───────┼──────┤
│ 0 │ 技术 │ 18000│
│ 1 │ 产品 │ 22000│
│ 2 │ 技术 │ 35000│
│ 3 │ 设计 │ 16000│
│ 4 │ 产品 │ 20000│
└────┴───────┴──────┘
↓ groupby('部门')
┌─────────────────────────────┐
│ 分组: │
│ 技术 → [18000, 35000] │
│ 产品 → [22000, 20000] │
│ 设计 → [16000] │
└─────────────────────────────┘
↓ agg('mean')
┌─────────────────────────────┐
│ 技术: 26500 │
│ 产品: 21000 │
│ 设计: 16000 │
└─────────────────────────────┘
agg vs transform:
agg → 返回每组一个值(缩减)
transform → 返回与原 DataFrame 等长的结果
4. 时间序列 resample
原始日数据:
│ ▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌│ 31 天
└────────────────────────────────────┘
resample('W') 按周汇总:
│ ▌▌▌▌▌▌▌│▌▌▌▌▌▌▌│▌▌▌▌▌▌▌│▌▌▌▌▌▌▌│ 4-5 周
└────────┘────────┘────────┘────────┘
resample('M') 按月汇总:
│ ▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌│ 1 个月
└─────────────────┘
resample('Q') 按季度汇总:
│ ▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌▌│ 1 个季度
└────────────────────────────────────┘
rolling(7) 滚动窗口:
│ [───────] 窗口 1
│ [───────] 窗口 2(向右滑动)
│ [───────] 窗口 3
│ ... 依次滑动
└────────────────────────────────────┘