正文内容
本文档是 Konrad Hinsen 于 2001 年撰写的 Numerical Python 教程,基于早期的 Numeric 模块(NumPy 的前身)。原为 Scientific Python 项目的一部分,由法国 CNRS 奥尔良分子生物学中心编写。
核心主题
教程系统介绍了 Numeric 数组的创建、索引、算术运算及与 C/Fortran 的接口方式。覆盖范围包括:
- 数组基础:多维数组的创建(
zeros、array、arange、fromfunction)、shape 属性、typecode - 索引与切片:基本索引、多轴索引(
a[0,...,1])、步长切片(a[::-1]、a[::2])、负索引、NewAxis插入新维度 - 数组算术:逐元素运算、广播(行/列广播)、in-place 运算(
a += 3)、比较运算 - 数学函数:
sqrt、log、sin、cos等同时适用于标量和数组 - 二元通用函数:
add、multiply的 reduce、accumulate、outer 操作 - 结构操作:
take(按索引选取)、where(条件选取)、reshape/resize、repeat - 引用语义:索引产生引用而非副本,修改子数组会影响原数组——这是重要但易错的特性
与 C/Fortran 的接口
- C 接口:通过
PyArrayObject和PyArg_ParseTuple将 Python 数组传给 C 函数,用Py_BuildValue返回结果 - Fortran 接口:通过 Pyfort 或手动写 C 包装层调用 Fortran 库;需注意机器字节序和编译器差异
- 添加模块:LinearAlgebra(LAPACK)、FFT(FFTPACK)、RNG(RANLIB)等扩展模块
效率要点
- 大数组运算接近纯 C 代码速度
- 小数组有解释器+数组开销,显式 Python 循环效率低
- 中间结果会分配临时数组,对大数组建议多用 in-place 运算
- 性能关键路径应移至 C 扩展模块
与现代表达式的对照
| Numeric(本文) | 现代 NumPy |
|---|---|
from Numeric import * | import numpy as np |
Numeric.array | np.array |
add.reduce(a) | np.sum(a) / a.sum() |
add.outer(a, b) | np.outer(a, b) |
resize(a, shape) | np.resize(a, shape) |
fromfunction(f, shape) | np.fromfunction(f, shape) |
历史意义
本教程是 Python 科学计算早期(pre-NumPy 时代)最重要的入门文档之一。Konrad Hinsen 后来创建了 Biopython 并长期维护 Scientific Python。虽然 Numeric 模块早已由 NumPy 取代(后者改进了内存模型和泛型支持),但大多数核心概念(广播、切片、ufunc、结构操作)在 NumPy 中完全延续。