>>>PyPathPython 学习站
前沿与实践 · Frontier & Practice lv.4 前沿 kp-041

数据科学生态(NumPy/Pandas/Polars)

前置知识:kp-034、kp-032

1. 一句话定义

Python 数据科学的三大支柱:NumPy(C 层多维数组与向量化运算的地基)、pandas(表级数据分析的通用语)、Polars(Rust 实现、多线程、惰性的新一代表引擎)。

2. 为什么重要

这是 Python 在 AI 时代统治地位的技术根源:语言层慢不要紧,把循环下沉到 C/Rust 后速度反而领先。理解"向量化思维"是数据方向 Pythoner 的核心心智转变。

3. 前置知识

kp-034(性能漏斗)、kp-010(表数据的纯 Python 版)。

4. 核心概念

python
import numpy as np

# NumPy:同构数组 + 广播
a = np.arange(1_000_000)
%timeit sum(a)          # Python 循环:慢
%timeit a.sum()         # C 向量化:快 100×+

b = a.reshape(-1, 1000)
b * 2                    # 广播:形状自动对齐

python
import pandas as pd

# pandas:DataFrame 即带标签的表格
df = pd.read_csv("scores.csv")
df.groupby("class")["score"].mean()          # 分组聚合(split-apply-combine)
df.query("score >= 60").sort_values("score")  # 链式过滤

python
import polars as pl

# Polars:惰性执行 + 多线程 + 列式内存
lazy = (
    pl.scan_csv("scores.csv")                # 惰性:先描述计划
      .filter(pl.col("score") >= 60)
      .group_by("class")
      .agg(pl.col("score").mean())
)
lazy.collect(streaming=True)                 # 此时才执行,可流式

5. 原理与机制

text
为什么向量化快:
  Python 循环:每迭代一次 = 解释器派发字节码 + 对象装箱拆箱(kp-001)
  NumPy 循环:整段运算下沉为一次 C 函数调用,SIMD/连续内存,无装箱

引擎选型(2025 年代心智):
  小探索/教程生态最全      → pandas
  大数据/生产管道/多线程   → Polars(或 pandas + PyArrow 后端)
  数值计算底座/自己写算法  → NumPy
  超出内存                → Polars streaming / DuckDB / Spark

Jupyter/ipython 是该方向的默认工作台(REPL 的增强版,支持 ? 查文档、%%time 测时)。

6. 关键事实(模型/图示)

text
一条铁律贯穿全生态:
  能向量化就不要写 for——把"对每行做什么"翻译成"对整列做什么"
  df["c"] = df["a"] + df["b"]        ✓ 向量化
  for i in rows: df["c"][i] = ...    ✗ 行循环(慢 100-1000×)

7. 直观类比

纯 Python 处理表格像会计逐行翻账本;向量化像把整列复印到算盘上一次算完(C 一次算一列);Polars 的惰性执行像先看整体菜单再规划厨房动线(查询优化器先重排步骤、合并过滤,然后多灶台并行开火)。

8. 实例与案例

python
# 同一任务的三个引擎(成绩单聚合)
# pandas:
df.groupby("class")["score"].mean()
# Polars:
df.group_by("class").agg(pl.col("score").mean())
# 纯 Python(对照组):
means = defaultdict(list)
for row in rows: means[row["class"]].append(row["score"])
{k: sum(v)/len(v) for k, v in means.items()}

9. 常见误区

  1. pandas 里写行循环/iterrows —— 反模式之王;先找向量化表达。
  2. 链式赋值 SettingWithCopy 警告无视 —— .loc 明确索引,或 copy() 明确意图。
  3. 以为 pandas=数据科学全部 —— 它是表层;NumPy 才是地基,统计建模在 statsmodels/sklearn。
  4. 大表盲目全载入内存 —— 分块/流式(Polars streaming、DuckDB、parquet 列存)。

10. 自测题

  1. 为什么 a.sum()(NumPy)比 sum(a) 快两个数量级?
  2. pandas 与 Polars 的最大架构差异?
  3. "向量化思维"的一句话表述?
参考答案
  1. 前者一次 C 调用处理连续内存的数值缓冲(无字节码派发、无 Python 对象装箱);后者在解释器里对 100 万个 Python 对象逐个运算。
  2. pandas 急切执行(eager)+ 单线程(默认);Polars 惰性查询优化 + Rust 多线程 + 列式存储。
  3. 把"逐行做什么"改写为"整列做什么",让循环下沉到 C/Rust 层。

11. 与其他知识点的关系

  • kp-044 AI 生态:PyTorch 的张量即 NumPy 心智的 GPU 版。
  • kp-011 推导式:纯 Python 侧的"声明式"对照。
  • kp-034 性能:向量化是漏斗第 5 级。

12. 延伸阅读

  • NumPy 快速上手:https://numpy.org/doc/stable/user/quickstart.html
  • Polars 用户指南:https://docs.pola.rs/
  • pandas 10 minutes to pandas