跳到主要内容

NumPy

问题

NumPy 的 ndarray 和 Python 列表有什么区别?广播机制是什么?

答案

ndarray vs list

import numpy as np

# Python list:元素类型可不同,存储为指针数组
py_list = [1, 2.0, "three"]

# ndarray:同类型、连续内存、支持向量化运算
arr = np.array([1, 2, 3, 4], dtype=np.float64)
特性Python listNumPy ndarray
类型任意混合单一类型(dtype)
内存指针数组连续内存块
运算逐元素循环向量化(C 实现)
速度快 10-100x

向量化运算

a = np.array([1, 2, 3])
b = np.array([4, 5, 6])

# 逐元素运算(无需 for 循环)
c = a + b # [5, 7, 9]
d = a * b # [4, 10, 18]
e = np.dot(a, b) # 32(点积)

# 矩阵运算
A = np.array([[1, 2], [3, 4]])
B = np.array([[5, 6], [7, 8]])
C = A @ B # 矩阵乘法

广播(Broadcasting)

当两个数组形状不同时,NumPy 自动扩展维度:

# 规则:从右对齐,维度为 1 或相等才能广播
a = np.array([[1, 2, 3], # shape (2, 3)
[4, 5, 6]])
b = np.array([10, 20, 30]) # shape (3,) → 广播为 (2, 3)

c = a + b
# [[11, 22, 33],
# [14, 25, 36]]

常用操作

# 形状操作
arr = np.arange(12) # [0, 1, ..., 11]
matrix = arr.reshape(3, 4) # 3x4 矩阵
flat = matrix.ravel() # 展平

# 索引与切片
matrix[0, :] # 第一行
matrix[:, 1] # 第二列
matrix[matrix > 5] # 布尔索引

# 聚合
matrix.sum(axis=0) # 按列求和
matrix.mean(axis=1) # 按行求均值

常见面试问题

Q1: NumPy 为什么快?

答案

  1. 连续内存:数据紧密排列,CPU 缓存命中率高
  2. C 实现:核心运算用 C/Fortran 编写,无 Python 解释器开销
  3. SIMD 指令:利用 CPU 向量化指令并行处理多个数据
  4. 避免循环:向量化操作替代 Python for 循环

Q2: copy()view() 的区别?

答案

a = np.array([1, 2, 3, 4])
b = a[1:3] # view(浅拷贝,共享内存)
c = a[1:3].copy() # 深拷贝

b[0] = 99
print(a) # [1, 99, 3, 4]——a 也变了

Q3: C-order 和 F-order 的区别?

答案

  • C-order(行优先,默认):同一行的元素在内存中连续
  • F-order(列优先):同一列的元素在内存中连续

遍历时按内存顺序访问性能最好。NumPy 默认 C-order,与 Python 的行循环习惯一致。

相关链接