01 - NumPy基础¶
学习时间: 3-4小时 重要性: ⭐⭐⭐⭐⭐ 所有科学计算的基础
🎯 学习目标¶
- 掌握NumPy数组的创建和操作
- 理解向量化运算的优势
- 学会数组索引和切片
📦 NumPy简介¶
Python
import numpy as np
# 为什么用NumPy?
# 1. 快速:C语言实现,比Python列表快10-100倍
# 2. 方便:向量化运算,不需要循环
# 3. 强大:丰富的数学函数
# 基本对比
import time
# Python列表
size = 1000000
python_list = list(range(size))
start = time.time()
result = [x * 2 for x in python_list]
print(f"Python列表: {time.time() - start:.4f}秒")
# NumPy数组
numpy_array = np.arange(size)
start = time.time()
result = numpy_array * 2
print(f"NumPy数组: {time.time() - start:.4f}秒")
🔢 数组创建¶
基本方法¶
Python
import numpy as np
# 从列表创建
arr = np.array([1, 2, 3, 4, 5])
print(arr) # [1 2 3 4 5]
print(type(arr)) # <class 'numpy.ndarray'>
# 多维数组
arr2d = np.array([[1, 2, 3], [4, 5, 6]])
print(arr2d.shape) # (2, 3) - 2行3列
# 常用创建方法
zeros = np.zeros((3, 4)) # 全0数组
ones = np.ones((2, 3)) # 全1数组
full = np.full((2, 3), 7) # 填充特定值
random = np.random.random((2, 3)) # 随机数
# 序列
range_arr = np.arange(0, 10, 2) # [0 2 4 6 8]
linspace = np.linspace(0, 1, 5) # [0. 0.25 0.5 0.75 1.]
# 常用特殊数组
eye = np.eye(3) # 单位矩阵
数组属性¶
Python
arr = np.array([[1, 2, 3], [4, 5, 6]])
print(arr.shape) # (2, 3) 形状
print(arr.ndim) # 2 维度
print(arr.size) # 6 元素总数
print(arr.dtype) # int64 数据类型
print(arr.itemsize) # 8 每个元素大小(字节)
🔍 索引与切片¶
基本索引¶
Python
arr = np.array([1, 2, 3, 4, 5])
# 一维数组
print(arr[0]) # 1 第一个元素
print(arr[-1]) # 5 最后一个元素
print(arr[1:4]) # [2 3 4] 切片
print(arr[::2]) # [1 3 5] 每隔一个
# 二维数组
arr2d = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
print(arr2d[0, 0]) # 1
print(arr2d[1, 2]) # 6
print(arr2d[0, :]) # [1 2 3] 第一行
print(arr2d[:, 0]) # [1 4 7] 第一列
print(arr2d[1:, 1:]) # [[5 6] [8 9]] 子矩阵
布尔索引¶
Python
arr = np.array([1, 2, 3, 4, 5, 6])
# 条件筛选
mask = arr > 3
print(mask) # [False False False True True True]
print(arr[mask]) # [4 5 6]
# 直接使用条件
evens = arr[arr % 2 == 0] # [2 4 6]
# 多条件
filtered = arr[(arr > 2) & (arr < 6)] # [3 4 5]
➗ 数组运算¶
向量化运算¶
Python
a = np.array([1, 2, 3, 4])
b = np.array([5, 6, 7, 8])
# 基本运算
print(a + b) # [6 8 10 12]
print(a - b) # [-4 -4 -4 -4]
print(a * b) # [5 12 21 32]
print(a / b) # [0.2 0.333 0.428 0.5]
print(a ** 2) # [1 4 9 16]
# 标量运算
print(a + 10) # [11 12 13 14]
print(a * 2) # [2 4 6 8]
# 数学函数
print(np.sqrt(a)) # [1. 1.414 1.732 2.]
print(np.exp(a)) # 指数
print(np.log(a)) # 对数
print(np.sin(a)) # 三角函数
广播机制¶
Python
# 不同形状的数组可以运算
a = np.array([[1, 2, 3], [4, 5, 6]]) # (2, 3)
b = np.array([10, 20, 30]) # (3,)
# b会自动"广播"以匹配a的形状
print(a + b)
# [[11 22 33]
# [14 25 36]]
# 标量会广播到所有元素
print(a * 10)
# [[10 20 30]
# [40 50 60]]
📊 统计与聚合¶
Python
arr = np.array([[1, 2, 3], [4, 5, 6]])
# 基本统计
print(arr.sum()) # 21 总和
print(arr.mean()) # 3.5 平均值
print(arr.std()) # 标准差
print(arr.var()) # 方差
print(arr.min()) # 1 最小值
print(arr.max()) # 6 最大值
print(arr.argmin()) # 0 最小值索引
print(arr.argmax()) # 5 最大值索引
# 沿轴操作
print(arr.sum(axis=0)) # [5 7 9] 列求和
print(arr.sum(axis=1)) # [6 15] 行求和
print(arr.mean(axis=0)) # [2.5 3.5 4.5] 列平均
🔄 数组变形¶
Python
arr = np.arange(12) # [0 1 2 ... 11]
# 改变形状
reshaped = arr.reshape(3, 4)
# [[0 1 2 3]
# [4 5 6 7]
# [8 9 10 11]]
# 转置
transposed = reshaped.T
# 展平
flattened = reshaped.flatten() # 返回副本
raveled = reshaped.ravel() # 返回视图(可能)
# 拼接
a = np.array([1, 2, 3])
b = np.array([4, 5, 6])
concat = np.concatenate([a, b]) # [1 2 3 4 5 6]
vstack = np.vstack([a, b]) # 垂直堆叠
hstack = np.hstack([a, b]) # 水平堆叠
# 分割
arr = np.arange(12).reshape(3, 4)
split = np.split(arr, 3, axis=0) # 按行分割
💡 实用技巧¶
技巧1: 避免循环¶
Python
# ❌ 不好
result = []
for i in range(len(data)):
if data[i] > 0:
result.append(data[i] * 2)
# ✅ 好
result = data[data > 0] * 2
技巧2: 内存视图¶
Python
a = np.arange(10)
b = a[2:5] # 视图,不是副本
b[0] = 100
print(a[2]) # 100!原数组被修改
# 如需副本,显式复制
c = a[2:5].copy()
📝 练习¶
- 创建一个5x5的随机矩阵,计算每行的平均值
- 将一个10x10的矩阵转置并乘以2
- 筛选出数组中大于平均值的所有元素
🎯 自我检查¶
- 能创建各种形状的数组
- 熟练使用索引和切片
- 理解向量化运算
- 能进行基本的数组运算和统计
下一步: 02 - Pandas入门