Python中使用NumPy进行高效数组运算的示例代码详解

原创 2025-07-17 10:24:38编程技术
793

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.]

python.webp

五、随机数生成

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的核心优势在于:

  1. 高性能:底层使用C实现,运算速度远超原生Python

  2. 便捷性:提供简洁的语法实现复杂数组操作

  3. 多功能性:支持从基础运算到高级科学计算的各种需求

  4. 生态集成:与SciPy、Pandas、Matplotlib等库无缝协作

掌握NumPy是进行Python科学计算的基础,建议读者通过实际项目练习巩固这些知识,逐步提升数据处理能力。

Python NumPy
THE END
战地网
频繁记录吧,生活的本意是开心

相关推荐

Python yield 用法大全:轻松掌握生成器与迭代器设计
在Python中,yield关键字是构建生成器的核心工具,它通过状态保存机制实现了高效的内存管理和惰性计算。与传统的迭代器实现相比,yield能将迭代器设计从复杂的类定义简化为直...
2025-09-15 编程技术
1207

基于Python的旅游数据分析可视化系统【2026最新】
本研究成功开发了基于Python+Django+Vue+MySQL的旅游数据分析可视化系统,实现了从数据采集到可视化展示的全流程管理。系统采用前后端分离架构,前端通过Vue框架构建响应式界...
2025-09-13 编程技术
1152

手把手教你用Python读取txt文件:从基础到实战的完整教程
Python作为数据处理的利器,文件读写是其基础核心功能。掌握txt文件读取不仅能处理日志、配置文件等常见场景,更是理解Python文件I/O的基石。本文ZHANID工具网将从基础语法到...
2025-09-12 编程技术
1069

Python Flask 入门指南:从零开始搭建你的第一个 Web 应用
Flask作为 Python 中最轻量级且灵活的 Web 框架之一,特别适合初学者快速上手 Web 应用开发。本文将带你一步步了解如何在本地环境中安装 Flask、创建一个简单的 Web 应用,并...
2025-09-11 编程技术
1011

Python 如何调用 MediaPipe?详细安装与使用指南
MediaPipe 是 Google 开发的跨平台机器学习框架,支持实时处理视觉、音频和文本数据。本文脚本之家将系统讲解 Python 环境下 MediaPipe 的安装、配置及核心功能调用方法,涵盖...
2025-09-10 编程技术
1082

基于Python开发一个利率计算器的思路及示例代码
利率计算是金融领域的基础需求,涵盖贷款利息、存款收益、投资回报等场景。传统计算依赖手工公式或Excel表格,存在效率低、易出错等问题。Python凭借其简洁的语法和强大的数学...
2025-09-09 编程技术
1097