NumPy是Python科学计算的基石,其核心是提供了高性能的多维数组对象 ndarray,以及基于它的海量数学函数库。
简单来说,它的主要优势就是快 和省。它解决了Python原生列表在进行大量数值计算时效率低下的问题。NumPy数组中的所有元素类型是统一的,数据在内存中连续存储,这带来了两个关键好处:
- 极致的运算速度:通过"向量化"操作,你可以直接对整个数组进行数学运算,避免使用低效的Python循环。这种底层由C语言实现的运算,速度比普通Python列表快上1到2个数量级。
- 高效的内存使用:由于数据类型统一且连续存储,NumPy数组占用的内存空间远小于同等情况下的Python列表,能更高效地处理海量数据。
正因如此,NumPy成为了Pandas、SciPy、Scikit-learn、TensorFlow和PyTorch等众多顶级数据科学和机器学习库的基础。
📦 核心数据结构:ndarray
ndarray(N-dimensional array,N维数组)是NumPy的主角。你可以把它看作是一个定义了多维度的、同质化的"表格"或"网格"。每个ndarray都有几个关键属性,你可以通过下面的方式查看:
python
import numpy as np
arr = np.array([[1, 2, 3], [4, 5, 6]])
print(arr.shape) # 输出: (2, 3) -> 表示这是一个2行3列的二维数组
print(arr.ndim) # 输出: 2 -> 表示数组的维度是2
print(arr.dtype) # 输出: int64 -> 表示数组元素的类型是64位整数
🛠️ 三大应用场景
- 数据处理与分析:对海量数据执行快速的统计、清洗和转换,如计算销售数据的平均值、标准差,或对金融时间序列进行移动平均。
- 科学计算与模拟:进行线性代数、傅里叶变换等复杂运算,是物理学模拟、工程计算等领域的基础工具。
- 作为AI/机器学习的基础 :图像、文本在输入到神经网络模型前,都会被转换为NumPy数组进行处理。例如,一张彩色图片可以轻松地表示为一个
(高度, 宽度, 3)的三维数组,其中"3"代表RGB三个颜色通道。
📚 常用函数速查表
🏗️ 创建数组 (Creation)
| 函数 | 描述 | 示例 |
|---|---|---|
np.array([1, 2, 3]) |
从列表创建数组 | arr = np.array([1, 2, 3]) |
np.zeros( (2,3) ) |
创建全0数组 | np.zeros((2,3)) → 2行3列的全0矩阵 |
np.ones( (2,3) ) |
创建全1数组 | np.ones((2,3)) → 2行3列的全1矩阵 |
np.arange(0, 10, 2) |
创建等差序列(类似range) |
np.arange(0, 10, 2) → array([0, 2, 4, 6, 8]) |
np.linspace(0, 1, 5) |
创建等间隔的等差数列 | np.linspace(0, 1, 5) → array([0., 0.25, 0.5, 0.75, 1.]) |
np.random.rand(2,3) |
创建[0, 1)均匀分布的随机数组 | 生成一个2x3的随机数矩阵 |
np.eye(3) |
创建单位矩阵 | np.eye(3) → 3x3的单位矩阵 |
📐 数组操作 (Manipulation)
| 函数/操作 | 描述 | 示例 |
|---|---|---|
arr.reshape(3, 2) |
改变数组的形状 | np.arange(6).reshape(2,3) → 将1维数组变为2x3的矩阵 |
arr[arr > 5] |
布尔索引,筛选满足条件的元素 | arr[arr > 5] → 返回数组中所有大于5的元素 |
np.where(条件, x, y) |
根据条件,返回x或y | np.where(arr > 5, 1, 0) → 大于5的设为1,否则设为0 |
np.hstack((a, b)) |
水平(按列)拼接 | 将两个数组左右拼接在一起 |
np.vstack((a, b)) |
垂直(按行)拼接 | 将两个数组上下堆叠在一起 |
➕ 数学和统计 (Math & Stats)
| 函数 | 描述 | 示例 |
|---|---|---|
np.sum(arr), np.mean(arr) |
求和,求平均值 | np.mean(arr, axis=0) → 计算每一列的平均值 |
np.max(arr), np.min(arr) |
求最大值,最小值 | arr.max() → 返回数组中的最大值 |
np.std(arr), np.var(arr) |
求标准差,方差 | 衡量数据的离散程度 |
np.argmax(arr) |
求最大值的索引(位置) | 常用于找出"冠军"所在的位置 |
np.dot(a, b) |
矩阵点乘/内积 | 执行真正的矩阵乘法,而不是对应元素相乘 |
arr.T |
矩阵转置 | arr.T → 返回原矩阵的转置 |
💻 代码示例:从入门到实践
1. 入门演示:效率差异
下面的例子展示了向量化运算的威力,同样是让100万个数字乘以2,NumPy的速度比Python列表快了几十倍。
python
import numpy as np
import time
# Python 列表
python_list = list(range(1_000_000))
start = time.time()
result = [x * 2 for x in python_list]
print(f"Python列表耗时: {time.time() - start:.4f}秒")
# NumPy 数组
numpy_array = np.arange(1_000_000)
start = time.time()
result = numpy_array * 2 # 简洁的向量化操作
print(f"NumPy数组耗时: {time.time() - start:.4f}秒")
# 输出示例:
# Python列表耗时: 0.0523秒
# NumPy数组耗时: 0.0012秒
2. 数据处理实战:股票分析
假设你有一家公司股票的每日收盘价,想分析它的表现,用NumPy可以轻松搞定。
python
import numpy as np
# 过去10天的股票收盘价
prices = np.array([100, 102, 101, 105, 107, 106, 108, 110, 109, 112])
# 1. 基础统计
print(f"平均价格: {np.mean(prices):.2f}")
print(f"最高价格: {np.max(prices)}")
print(f"价格波动(标准差): {np.std(prices):.2f}")
# 2. 找出价格超过108的交易日
print(f"价格超过108的日子: {np.where(prices > 108)}") # 返回索引位置
# 3. 计算每日收益率(使用向量化运算)
# 收益率 = (今日价 - 昨日价) / 昨日价
# 切片操作: prices[1:] 是第2天到第10天, prices[:-1] 是第1天到第9天
returns = (prices[1:] - prices[:-1]) / prices[:-1]
print(f"每日收益率: {returns}")
# 4. 找出收益率最高的那一天
max_return_day = np.argmax(returns) + 1 # +1 是因为returns的长度比prices少1
print(f"收益率最高的日子是第 {max_return_day} 天,收益率为 {np.max(returns)*100:.2f}%")