正文内容

本文档是 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.arraynp.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 中完全延续。