← 返回 Day 103 正文

Day 103 · 图解

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
│          ...    依次滑动
└────────────────────────────────────┘