NumPy是Python科学计算的基础库,它提供了高性能的多维数组对象ndarray和丰富的数组运算功能。相比原生Python列表,NumPy数组在内存存储和运算效率上具有显著优势,特别适合处理大规模数值数据。本文ZHANID工具网将通过30个具体示例,详细讲解NumPy的核心功能,包括数组创建、索引切片、数学运算、线性代数、随机数生成等,帮助读者掌握NumPy的高效使用方法。
一、NumPy基础:数组创建与属性
1. 创建一维数组
import numpy as np # 从Python列表创建 arr1 = np.array([1, 2, 3, 4, 5]) print(arr1) # 输出: [1 2 3 4 5] print(type(arr1)) # 输出: <class 'numpy.ndarray'>
NumPy数组是同类型元素的集合,创建时会自动推断数据类型:
# 指定数据类型 arr2 = np.array([1.2, 3.5, 4.8], dtype=np.float32) print(arr2.dtype) # 输出: float32
2. 创建多维数组
# 从嵌套列表创建二维数组 matrix = np.array([[1, 2, 3], [4, 5, 6]]) print(matrix) """ 输出: [[1 2 3] [4 5 6]] """ print(matrix.shape) # 输出: (2, 3) 表示2行3列
3. 特殊数组创建函数
NumPy提供了多种快速创建特殊数组的方法:
# 全零数组 zeros = np.zeros((3, 4)) # 3行4列的零矩阵 print(zeros) # 全一数组 ones = np.ones((2, 2)) print(ones) # 单位矩阵 eye = np.eye(3) # 3x3单位矩阵 print(eye) # 等差数列数组 arange = np.arange(0, 10, 2) # 从0开始,步长2,不到10 print(arange) # 输出: [0 2 4 6 8] # 等间隔数组 linspace = np.linspace(0, 1, 5) # 在[0,1]区间生成5个等间隔数 print(linspace) # 输出: [0. 0.25 0.5 0.75 1. ]
4. 数组属性详解
arr = np.array([[1, 2, 3], [4, 5, 6]])
print("数组维度:", arr.ndim) # 输出: 2 (二维数组)
print("数组形状:", arr.shape) # 输出: (2, 3) (2行3列)
print("元素总数:", arr.size) # 输出: 6 (2*3)
print("元素类型:", arr.dtype) # 输出: int64 (默认整数类型)
print("字节大小:", arr.itemsize) # 输出: 8 (每个int64占8字节)
print("总字节数:", arr.nbytes) # 输出: 48 (6*8)二、数组索引与切片操作
5. 一维数组索引
arr = np.array([10, 20, 30, 40, 50]) print(arr[0]) # 输出: 10 (第一个元素) print(arr[-1]) # 输出: 50 (最后一个元素) print(arr[1:4]) # 输出: [20 30 40] (索引1到3)
6. 多维数组索引
matrix = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]]) # 获取第二行所有元素 print(matrix[1, :]) # 输出: [4 5 6] # 获取第三列所有元素 print(matrix[:, 2]) # 输出: [3 6 9] # 获取子矩阵 print(matrix[1:, :2]) # 输出: [[4 5], [7 8]]
7. 布尔索引应用
arr = np.array([1, 2, 3, 4, 5, 6]) # 获取大于3的元素 mask = arr > 3 print(mask) # 输出: [False False False True True True] print(arr[mask]) # 输出: [4 5 6] # 等价写法 print(arr[arr > 3]) # 输出: [4 5 6]
8. 花式索引(Fancy Indexing)
arr = np.array([10, 20, 30, 40, 50]) # 使用索引数组获取元素 indices = [1, 3, 4] print(arr[indices]) # 输出: [20 40 50] # 多维数组的花式索引 matrix = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]]) rows = [0, 1, 2] cols = [1, 2, 0] print(matrix[rows, cols]) # 输出: [2 6 7] (获取(0,1),(1,2),(2,0)元素)
三、数组运算与数学函数
9. 基本算术运算
a = np.array([1, 2, 3]) b = np.array([4, 5, 6]) print(a + b) # 输出: [5 7 9] (逐元素相加) print(a - b) # 输出: [-3 -3 -3] print(a * b) # 输出: [ 4 10 18] (不是矩阵乘法) print(a / b) # 输出: [0.25 0.4 0.5 ] print(a ** 2) # 输出: [1 4 9] (平方运算)
10. 标量与数组运算
arr = np.array([1, 2, 3]) print(arr + 10) # 输出: [11 12 13] print(arr * 2) # 输出: [2 4 6] print(arr ** 2) # 输出: [1 4 9]
11. 通用数学函数
NumPy提供了大量高效的数学函数:
arr = np.array([0, np.pi/2, np.pi]) print(np.sin(arr)) # 输出: [0.0000000e+00 1.0000000e+00 1.2246468e-16] print(np.cos(arr)) # 输出: [ 1.000000e+00 6.123234e-17 -1.000000e+00] print(np.exp(arr)) # 输出: [1. 4.81047738 23.14069263] print(np.log10(arr+1)) # 避免log(0)错误
12. 统计函数应用
data = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
print("最大值:", np.max(data)) # 输出: 9
print("最小值:", np.min(data)) # 输出: 1
print("平均值:", np.mean(data)) # 输出: 5.0
print("标准差:", np.std(data)) # 输出: 2.449489742783178
print("行求和:", np.sum(data, axis=1)) # 输出: [ 6 15 24] (沿行方向求和)
print("列求和:", np.sum(data, axis=0)) # 输出: [12 15 18] (沿列方向求和)四、线性代数运算
13. 矩阵乘法
A = np.array([[1, 2], [3, 4]]) B = np.array([[5, 6], [7, 8]]) # 矩阵乘法 (不是*运算符) print(np.dot(A, B)) """ 输出: [[19 22] [43 50]] """ # 或使用@运算符(Python 3.5+) print(A @ B)
14. 矩阵转置与逆
matrix = np.array([[1, 2], [3, 4]])
# 矩阵转置
print(matrix.T)
"""
输出:
[[1 3]
[2 4]]
"""
# 矩阵求逆
try:
inv_matrix = np.linalg.inv(matrix)
print(inv_matrix)
except np.linalg.LinAlgError:
print("矩阵不可逆")15. 行列式与特征值
matrix = np.array([[4, -2], [1, 1]])
# 计算行列式
det = np.linalg.det(matrix)
print("行列式:", det) # 输出: 6.0
# 计算特征值和特征向量
eigenvalues, eigenvectors = np.linalg.eig(matrix)
print("特征值:", eigenvalues)
print("特征向量:\n", eigenvectors)16. 解线性方程组
# 解方程组:
# 2x + y = 5
# x - y = 1
A = np.array([[2, 1], [1, -1]])
b = np.array([5, 1])
x = np.linalg.solve(A, b)
print("解:", x) # 输出: [2. 1.]
五、随机数生成
17. 基本随机数生成
# 生成0到1之间的随机数 rand_nums = np.random.rand(5) # 生成5个随机数 print(rand_nums) # 生成正态分布随机数 normal_nums = np.random.randn(5) # 标准正态分布 print(normal_nums) # 生成指定范围的随机整数 rand_ints = np.random.randint(0, 10, size=5) # 0到9之间的5个整数 print(rand_ints)
18. 随机数种子设置
# 设置随机种子保证结果可复现 np.random.seed(42) print(np.random.rand(3)) # 每次运行结果相同 np.random.seed(42) print(np.random.rand(3)) # 与上一次相同
19. 随机数组排列
arr = np.array([1, 2, 3, 4, 5]) # 随机排列数组 shuffled = np.random.permutation(arr) print(shuffled) # 输出: [3 1 5 2 4] (每次不同) # 生成随机排列的索引 indices = np.random.permutation(len(arr)) print(arr[indices]) # 等价于np.random.permutation(arr)
六、高级数组操作
20. 数组拼接与分割
a = np.array([1, 2, 3]) b = np.array([4, 5, 6]) # 水平拼接 hstack = np.hstack((a, b)) print(hstack) # 输出: [1 2 3 4 5 6] # 垂直拼接(需要二维数组) A = np.array([[1], [2], [3]]) B = np.array([[4], [5], [6]]) vstack = np.vstack((A, B)) print(vstack) """ 输出: [[1] [2] [3] [4] [5] [6]] """ # 数组分割 arr = np.arange(10) parts = np.array_split(arr, 3) # 分成3部分 for part in parts: print(part) """ 输出: [0 1 2 3] [4 5 6] [7 8 9] """
21. 数组广播机制
NumPy的广播机制允许不同形状的数组进行算术运算:
# 形状(3,)与形状(1,)的广播 a = np.array([1, 2, 3]) b = np.array([10]) print(a + b) # 输出: [11 12 13] # 形状(2,3)与形状(3,)的广播 A = np.array([[1, 2, 3], [4, 5, 6]]) b = np.array([10, 20, 30]) print(A + b) """ 输出: [[11 22 33] [14 25 36]] """
22. 数组的保存与加载
# 保存数组到文件
arr = np.arange(10)
np.save('array_data.npy', arr) # 保存为.npy格式
np.savetxt('array_data.txt', arr, delimiter=',') # 保存为文本文件
# 从文件加载数组
loaded_npy = np.load('array_data.npy')
loaded_txt = np.loadtxt('array_data.txt', delimiter=',')
print(loaded_npy)
print(loaded_txt)七、性能优化技巧
23. 向量化运算优势
# 非向量化实现(Python列表)
def sum_list(n):
lst = range(n)
total = 0
for x in lst:
total += x**2
return total
# 向量化实现(NumPy数组)
def sum_array(n):
arr = np.arange(n)
return np.sum(arr**2)
# 性能比较
import timeit
n = 1000000
print("列表耗时:", timeit.timeit(lambda: sum_list(n), number=10)/10)
print("数组耗时:", timeit.timeit(lambda: sum_array(n), number=10)/10)
# 数组实现通常快10-100倍24. 避免循环操作
# 低效实现(使用循环) arr = np.random.rand(1000, 1000) result = np.zeros_like(arr) for i in range(arr.shape[0]): for j in range(arr.shape[1]): result[i,j] = arr[i,j] * 2 + 10 # 高效实现(向量化运算) result_vec = arr * 2 + 10 # 验证结果是否相同 print(np.allclose(result, result_vec)) # 输出: True
25. 内存预分配
# 低效方式(动态扩展数组) def dynamic_append(n): result = [] for i in range(n): result.append(i**2) return np.array(result) # 高效方式(预分配内存) def preallocated(n): result = np.empty(n) for i in range(n): result[i] = i**2 return result # 对于大型数组,预分配方式更快
八、实际应用案例
26. 图像处理基础
from PIL import Image
import matplotlib.pyplot as plt
# 加载图像并转换为NumPy数组
img = Image.open('example.jpg') # 替换为实际图片路径
img_array = np.array(img)
# 显示图像形状和类型
print("图像形状:", img_array.shape) # (高度, 宽度, 通道数)
print("数据类型:", img_array.dtype) # 通常是uint8
# 图像灰度化
if len(img_array.shape) == 3:
gray_array = np.dot(img_array[...,:3], [0.299, 0.587, 0.114]).astype(np.uint8)
plt.imshow(gray_array, cmap='gray')
plt.show()27. 金融时间序列分析
# 生成模拟股票价格数据
np.random.seed(42)
days = 100
initial_price = 100
daily_returns = np.random.normal(0.001, 0.02, days)
prices = initial_price * (1 + daily_returns).cumprod()
# 计算移动平均线
window_size = 20
moving_avg = np.convolve(prices, np.ones(window_size)/window_size, mode='valid')
# 绘制结果
import matplotlib.pyplot as plt
plt.figure(figsize=(10,6))
plt.plot(prices, label='Price')
plt.plot(np.arange(window_size-1, days), moving_avg, label=f'{window_size}-Day MA')
plt.legend()
plt.show()28. 科学计算示例:求解热传导方程
# 有限差分法求解一维热传导方程
def heat_equation_solver(L=1.0, T=0.1, nx=100, nt=1000, alpha=0.01):
dx = L / (nx - 1)
dt = T / nt
r = alpha * dt / (dx**2)
# 初始条件
u = np.zeros(nx)
u[int(0.4/dx):int(0.6/dx)] = 1.0 # 初始热源
# 边界条件
u[0] = 0
u[-1] = 0
# 时间推进
for _ in range(nt):
un = u.copy()
u[1:-1] = un[1:-1] + r * (un[2:] - 2*un[1:-1] + un[:-2])
return np.linspace(0, L, nx), u
x, u = heat_equation_solver()
plt.plot(x, u)
plt.xlabel('Position')
plt.ylabel('Temperature')
plt.title('Heat Equation Solution')
plt.show()九、常见问题解决
29. 解决"ValueError: operands could not be broadcast together"
# 错误示例
A = np.ones((3, 4))
B = np.ones((2, 3))
try:
C = A + B # 形状不匹配无法广播
except ValueError as e:
print("错误:", e)
# 正确做法:确保形状兼容或显式调整形状
B_reshaped = B.T # 转置为(3,2)仍不匹配
# 需要进一步调整或重新设计计算方式30. 处理内存不足错误
# 对于大型数组操作,可以分块处理 def process_large_array(file_path, chunk_size=10000): # 假设文件包含大量数值数据 results = [] with open(file_path) as f: chunk = [] for i, line in enumerate(f): chunk.append(float(line.strip())) if (i+1) % chunk_size == 0: arr = np.array(chunk) # 处理数组块 results.append(np.mean(arr)) chunk = [] # 处理剩余数据 if chunk: arr = np.array(chunk) results.append(np.mean(arr)) return results
总结
本文通过30个具体示例,全面展示了NumPy在数组创建、索引切片、数学运算、线性代数、随机数生成等方面的高效使用方法。NumPy的核心优势在于:
高性能:底层使用C实现,运算速度远超原生Python
便捷性:提供简洁的语法实现复杂数组操作
多功能性:支持从基础运算到高级科学计算的各种需求
生态集成:与SciPy、Pandas、Matplotlib等库无缝协作
掌握NumPy是进行Python科学计算的基础,建议读者通过实际项目练习巩固这些知识,逐步提升数据处理能力。
本文由@战地网 原创发布。
该文章观点仅代表作者本人,不代表本站立场。本站不承担相关法律责任。
如若转载,请注明出处:https://www.zhanid.com/biancheng/5056.html




















