导航菜单

  • 1.vector
  • 2.milvus
  • 3.pymilvus
  • 4.rag
  • 5.rag_measure
  • 7.search
  • ragflow
  • heapq
  • HNSW
  • cosine_similarity
  • math
  • typing
  • etcd
  • minio
  • collections
  • jieba
  • random
  • beautifulsoup4
  • chromadb
  • sentence_transformers
  • numpy
  • lxml
  • openpyxl
  • PyMuPDF
  • python-docx
  • requests
  • python-pptx
  • text_splitter
  • all-MiniLM-L6-v2
  • openai
  • llm
  • BPETokenizer
  • Flask
  • RAGAS
  • BagofWords
  • langchain
  • Pydantic
  • abc
  • faiss
  • MMR
  • scikit-learn
  • 1. 什么是 NumPy?
  • 2. 环境准备
    • 2.1 检查 Python 版本
    • 2.2 安装 NumPy
    • 2.3 验证安装
  • 3. 核心概念
    • 3.1 ndarray(数组对象)
    • 3.2 维度(Dimensions)
    • 3.3 形状(Shape)
    • 3.4 数据类型(dtype)
  • 4. 创建数组
    • 4.1 从 Python 列表创建
    • 4.2 创建特殊数组
    • 4.3 查看数组属性
  • 5. 索引与切片
    • 5.1 基本索引
    • 5.2 切片操作
    • 5.3 布尔索引
    • 5.4 花式索引
  • 6. 数组操作
    • 6.1 改变数组形状
    • 6.2 拼接数组
    • 6.3 拆分数组
  • 7. 数学运算
    • 7.1 基本运算
    • 7.2 数学函数
  • 8. 统计函数
    • 8.1 基本统计
    • 8.2 按轴统计
  • 9. 随机数
    • 9.1 基本随机数生成
    • 9.2 随机选择与打乱
  • 10. 文件操作
    • 10.1 保存和加载
    • 10.2 批量保存和加载
  • 11. 实战案例:销售数据分析
  • 12. 性能优化与常见问题
    • 12.1 向量化 vs 循环
    • 12.2 数据类型选择
    • 12.3 广播机制
    • 12.4 常见问题
  • 13. 学习资源

1. 什么是 NumPy? #

NumPy(Numerical Python)是 Python 中最基础的数值计算库。它提供了高性能的多维数组对象(ndarray)以及丰富的数学函数。几乎所有的数据科学、机器学习、科学计算库都基于 NumPy。

为什么要用 NumPy?

想象一下,如果你想计算一个包含 100 万个数字的列表的每个元素的平方。使用 Python 的普通列表需要逐个处理,非常慢。但使用 NumPy 数组,一行代码就能完成,速度可以提升几十倍甚至上百倍。

NumPy 的优势:

  • 速度快:使用 C 语言实现,比 Python 原生列表快得多
  • 向量化计算:可以对整个数组进行数学运算,无需循环
  • 内存高效:存储相同的数据,NumPy 数组比 Python 列表占用更少内存
  • 丰富的功能:提供大量的数学、统计、线性代数函数
  • 生态基础:Pandas、Matplotlib、Scikit-learn 等都依赖 NumPy

前置知识补充:

  • 数组:数组是一个包含多个元素的数据结构,元素通常是同类型的(比如都是整数或都是浮点数)。一维数组就像一行数字,二维数组像表格,三维数组像立方体。
  • 向量:一维数组可以称为向量,比如 [1, 2, 3]。
  • 矩阵:二维数组可以称为矩阵,比如 [[1, 2], [3, 4]]。
  • 向量化计算:对数组中的每个元素同时执行相同的操作,比如对数组 [1, 2, 3] 的每个元素加 1,得到 [2, 3, 4]。

2. 环境准备 #

在学习 NumPy 之前,需要确保你的 Python 环境已经准备好。NumPy 支持 Python 3.8 及以上版本。

2.1 检查 Python 版本 #

在安装之前,先检查一下你的 Python 版本是否符合要求。

# Windows PowerShell:查看 Python 版本
python --version
# macOS 终端:查看 Python 版本
python3 --version

2.2 安装 NumPy #

NumPy 可以直接通过 pip 安装。安装过程会自动下载所需的依赖包。

# 说明:Windows PowerShell 安装 NumPy
# 先升级 pip 到最新版本,确保能正常安装依赖
python -m pip install --upgrade pip
# 安装 NumPy 库
python -m pip install numpy
# 说明:macOS / Linux 终端安装 NumPy
# 先升级 pip 到最新版本
python3 -m pip install --upgrade pip
# 安装 NumPy 库
python3 -m pip install numpy

网络加速提示:如果从 PyPI 下载较慢,可以使用国内镜像:

  • Windows: python -m pip install numpy -i https://pypi.tuna.tsinghua.edu.cn/simple
  • macOS: python3 -m pip install numpy -i https://pypi.tuna.tsinghua.edu.cn/simple

安装问题提示:在某些旧环境中可能遇到二进制轮子缺失的问题,可以尝试:

  • Windows: python -m pip install numpy --prefer-binary
  • macOS: python3 -m pip install numpy --prefer-binary 或者直接安装 Anaconda/Miniconda,它们自带 NumPy。

2.3 验证安装 #

安装完成后,验证一下是否安装成功。

方法/属性 功能说明 常用参数 返回值
np.array() 将 Python 列表转换为 NumPy 数组 object:要转换的列表或可迭代对象 ndarray 数组对象
ndarray 属性 数组的各种属性(如 shape、dtype 等) 无 对应属性值
# -*- coding: utf-8 -*-
# 说明:验证 NumPy 是否安装成功

# 说明:导入 NumPy 库
# 通常使用 np 作为 NumPy 的别名,这是约定俗成的做法
import numpy as np

# 说明:创建一个简单的数组进行测试
# array() 函数可以将 Python 列表转换为 NumPy 数组
test_array = np.array([1, 2, 3, 4, 5])

# 说明:打印数组,验证安装是否成功
print("安装成功!测试数组:", test_array)

# 说明:打印 NumPy 版本信息
print(f"NumPy 版本:{np.__version__}")

# 说明:如果没有报错并输出了数组,说明安装成功

3. 核心概念 #

在使用 NumPy 之前,需要理解几个核心概念。这些概念是理解 NumPy 的基础。

3.1 ndarray(数组对象) #

ndarray 是 NumPy 的核心,它是一个多维数组对象。所有元素必须是相同类型(比如都是整数或都是浮点数)。

3.2 维度(Dimensions) #

  • 0 维:标量(单个数字),如 42
  • 1 维:向量(一行数字),如 [1, 2, 3]
  • 2 维:矩阵(表格),如 [[1, 2], [3, 4]]
  • 3 维及以上:多维数组

3.3 形状(Shape) #

形状描述数组在每个维度上的大小。例如:

  • [1, 2, 3] 的形状是 (3,),表示有 3 个元素
  • [[1, 2], [3, 4]] 的形状是 (2, 2),表示有 2 行 2 列

3.4 数据类型(dtype) #

NumPy 数组中的元素必须是相同类型,比如:

  • int32:32 位整数
  • float64:64 位浮点数(小数)
  • bool:布尔值(True/False)

4. 创建数组 #

NumPy 提供了多种创建数组的方法,从 Python 列表转换是最常用的方式。

4.1 从 Python 列表创建 #

方法/属性 功能说明 常用参数 返回值
np.array() 将 Python 列表转换为 NumPy 数组 object:要转换的列表或可迭代对象 ndarray 数组对象
.shape 获取数组的形状(每个维度的大小) 无(属性) 元组,表示数组形状
# -*- coding: utf-8 -*-
# 说明:演示如何从 Python 列表创建 NumPy 数组

# 说明:导入 NumPy 库
import numpy as np

# 说明:从 Python 列表创建一维数组
# array() 函数将 Python 列表转换为 NumPy 数组
arr1 = np.array([1, 2, 3, 4, 5])
print("一维数组:", arr1)

# 说明:创建二维数组(矩阵形式)
# 传入一个嵌套列表,外层列表的每个元素是一行
arr2 = np.array([[1, 2, 3], [4, 5, 6]])
print("二维数组(2行3列):")
print(arr2)

# 说明:创建三维数组(较少使用,但了解即可)
# 三层嵌套列表
arr3 = np.array([[[1, 2], [3, 4]], [[5, 6], [7, 8]]])
print("三维数组:")
print(arr3)
print(f"形状:{arr3.shape}")  # 形状是 (2, 2, 2)

4.2 创建特殊数组 #

NumPy 提供了许多函数来创建常用的特殊数组。

方法/属性 功能说明 常用参数 返回值
np.zeros() 创建全零数组 shape:数组形状,如 (2, 3) 全零数组
np.ones() 创建全一数组 shape:数组形状,如 (3, 2) 全一数组
np.eye() 创建单位矩阵(对角线为1,其他为0) N:矩阵大小 单位矩阵
np.arange() 创建等差数列 start:起始值,stop:结束值(不包含),step:步长 等差数列
np.linspace() 创建等间隔数组 start:起始值,stop:结束值(包含),num:元素个数 等间隔数组
np.empty() 创建空数组(值未初始化) shape:数组形状 空数组(值随机)
# -*- coding: utf-8 -*-
# 说明:演示如何创建特殊的数组

# 说明:导入 NumPy 库
import numpy as np

# 说明:创建全零数组
# zeros() 函数创建一个全为 0 的数组
# 参数 (2, 3) 表示创建一个 2 行 3 列的数组
zeros = np.zeros((2, 3))
print("全零数组(2行3列):")
print(zeros)

# 说明:创建全一数组
# ones() 函数创建一个全为 1 的数组
# 参数 (3, 2) 表示创建一个 3 行 2 列的数组
ones = np.ones((3, 2))
print("\n全一数组(3行2列):")
print(ones)

# 说明:创建单位矩阵(对角线为 1,其他为 0)
# eye() 函数创建单位矩阵
# 参数 3 表示创建一个 3x3 的单位矩阵
identity = np.eye(3)
print("\n单位矩阵(3x3):")
print(identity)

# 说明:创建等差数列
# arange() 函数创建一个等差数列
# 参数:起始值、结束值(不包含)、步长
# 这里从 0 开始,到 10(不包含),步长为 2
range_arr = np.arange(0, 10, 2)
print("\n等差数列(0到10,步长2):", range_arr)

# 说明:创建等间隔数组
# linspace() 函数创建一个等间隔的数组
# 参数:起始值、结束值(包含)、元素个数
# 这里从 0 到 1(包含),创建 5 个等间隔的数
linspace_arr = np.linspace(0, 1, 5)
print("\n等间隔数组(0到1,5个数):", linspace_arr)

# 说明:创建空数组(未初始化,值是随机的)
# empty() 函数创建一个空数组(不初始化值,速度更快)
# 参数 (2, 3) 表示创建一个 2 行 3 列的数组
empty = np.empty((2, 3))
print("\n空数组(值未初始化):")
print(empty)

4.3 查看数组属性 #

了解数组的属性有助于更好地使用 NumPy。

本代码块中使用的 NumPy 属性:

属性 功能说明 返回值
.ndim 数组的维度数 整数(如 1 表示一维,2 表示二维)
.shape 数组的形状(每个维度的大小) 元组(如 (2, 3) 表示 2 行 3 列)
.size 数组中元素的总数 整数
.dtype 数组元素的数据类型 数据类型(如 int64、float64)
.itemsize 每个元素占用的字节数 整数(字节数)
.nbytes 数组占用的总字节数 整数(总字节数 = size × itemsize)
# -*- coding: utf-8 -*-
# 说明:演示如何查看数组的属性

# 说明:导入 NumPy 库
import numpy as np

# 说明:创建一个示例数组
arr = np.array([[1, 2, 3], [4, 5, 6]])

# 说明:查看数组的维度(维度数)
# ndim 属性返回数组的维度数
print("维度数:", arr.ndim)  # 2 维

# 说明:查看数组的形状(每个维度的大小)
# shape 属性返回一个元组,表示数组的形状
print("形状:", arr.shape)  # (2, 3) 表示 2 行 3 列

# 说明:查看数组的元素总数
# size 属性返回数组中元素的总数
print("元素总数:", arr.size)  # 2 * 3 = 6

# 说明:查看数组的数据类型
# dtype 属性返回数组中元素的数据类型
print("数据类型:", arr.dtype)  # int64(整数)

# 说明:查看数组的大小(字节数)
# itemsize 属性返回每个元素占用的字节数
print("每个元素的字节数:", arr.itemsize)  # 8 字节(int64)

# 说明:查看数组的总字节数
# nbytes 属性返回数组占用的总字节数
print("总字节数:", arr.nbytes)  # 6 * 8 = 48 字节

5. 索引与切片 #

索引和切片是访问和修改数组元素的重要方式。NumPy 的索引方式与 Python 列表类似,但支持多维索引。

5.1 基本索引 #

方法/操作 功能说明 常用参数 返回值
np.arange() 创建等差数列 start:起始值,stop:结束值(不包含) 等差数列
.reshape() 改变数组形状 shape:新形状,如 (3, 3) 重塑后的数组(视图)
arr[i, j] 访问数组中的单个元素 i:行索引,j:列索引 单个元素值
arr[i] 访问数组的第 i 行 i:行索引 第 i 行的数组
arr[:, j] 访问数组的第 j 列 j:列索引 第 j 列的数组
# -*- coding: utf-8 -*-
# 说明:演示基本的索引操作

# 说明:导入 NumPy 库
import numpy as np

# 说明:创建一个 3x3 的数组作为示例
# arange(1, 10) 创建 [1, 2, 3, 4, 5, 6, 7, 8, 9]
# reshape(3, 3) 将其重塑为 3 行 3 列
arr = np.arange(1, 10).reshape(3, 3)
print("原始数组:")
print(arr)

# 说明:访问单个元素
# 使用 [行索引, 列索引] 的方式访问
# 索引从 0 开始,第一个元素的索引是 0
element = arr[1, 1]  # 访问第 2 行第 2 列的元素
print(f"\n第2行第2列的元素:{element}")

# 说明:访问整行
# 只指定行索引,不指定列索引,返回整行
row = arr[0]  # 访问第 1 行
print(f"第1行:{row}")

# 说明:访问整列
# 使用 [:, 列索引] 的方式访问整列
# : 表示所有行
col = arr[:, 0]  # 访问第 1 列
print(f"第1列:{col}")

5.2 切片操作 #

切片可以获取数组的子集。

方法/操作 功能说明 常用参数 返回值
arr[start:end, start:end] 切片获取子数组 start:起始索引,end:结束索引(不包含) 子数组
arr[-1] 使用负数索引(从末尾开始) -1 表示最后一个元素 最后一个元素或行
arr[:, :] 获取所有行和所有列 无 完整的数组
# -*- coding: utf-8 -*-
# 说明:演示切片操作

# 说明:导入 NumPy 库
import numpy as np

# 说明:创建一个 3x3 的数组
arr = np.arange(1, 10).reshape(3, 3)
print("原始数组:")
print(arr)

# 说明:切片获取子数组
# 语法:arr[行起始:行结束, 列起始:列结束]
# 注意:结束索引不包含在结果中
# arr[0:2, 1:3] 表示第 1-2 行(索引 0-1),第 2-3 列(索引 1-2)
sub_arr = arr[0:2, 1:3]
print("\n子数组(第1-2行,第2-3列):")
print(sub_arr)

# 说明:使用负数索引(从末尾开始)
# -1 表示最后一个元素,-2 表示倒数第二个
last_row = arr[-1]  # 最后一行
print(f"\n最后一行:{last_row}")

# 说明:省略所有索引(获取所有行/列)
all_rows = arr[:, :]  # 获取所有行和所有列(等同于 arr)
print(f"\n所有行:")
print(all_rows)

5.3 布尔索引 #

布尔索引可以根据条件筛选数组元素。

方法/操作 功能说明 常用参数 返回值
arr > value 比较运算,返回布尔数组 value:比较值 布尔数组(True/False)
arr[mask] 使用布尔掩码筛选元素 mask:布尔数组 满足条件的元素数组
(条件1) & (条件2) 组合多个条件(且) 两个布尔条件 组合后的布尔数组
arr[condition] = value 根据条件修改元素 condition:布尔条件,value:新值 无(修改原数组)
# -*- coding: utf-8 -*-
# 说明:演示布尔索引(根据条件筛选元素)

# 说明:导入 NumPy 库
import numpy as np

# 说明:创建一个示例数组
arr = np.arange(1, 10).reshape(3, 3)
print("原始数组:")
print(arr)

# 说明:创建布尔掩码(条件)
# 比较运算返回一个布尔数组,其中 True 表示满足条件,False 表示不满足
mask = arr > 5
print("\n布尔掩码(大于5的元素为True):")
print(mask)

# 说明:使用布尔掩码筛选元素
# 只返回掩码中为 True 的位置对应的元素
filtered = arr[mask]
print("\n满足条件(大于5)的元素:", filtered)

# 说明:更复杂的条件
# 可以使用 &(且)、|(或)、~(非)组合多个条件
# 注意:必须使用括号
condition = (arr > 3) & (arr < 7)
result = arr[condition]
print("\n大于3且小于7的元素:", result)

# 说明:修改满足条件的元素
arr[arr > 5] = 0  # 将所有大于 5 的元素设置为 0
print("\n修改后(大于5的元素变为0):")
print(arr)

5.4 花式索引 #

花式索引可以根据索引列表选择元素。

方法/操作 功能说明 常用参数 返回值
arr[rows] 使用索引列表选择行 rows:行索引列表 选中的行数组
arr[rows, cols] 使用索引列表选择元素 rows:行索引列表,cols:列索引列表 选中的元素数组
np.ix_() 创建索引网格(用于矩形区域选择) rows:行索引列表,cols:列索引列表 索引网格元组
# -*- coding: utf-8 -*-
# 说明:演示花式索引(使用索引列表选择元素)

# 说明:导入 NumPy 库
import numpy as np

# 说明:创建一个示例数组
arr = np.arange(1, 10).reshape(3, 3)
print("原始数组:")
print(arr)

# 说明:使用索引列表选择特定行
# [0, 2] 表示选择第 1 行和第 3 行(索引 0 和 2)
rows = [0, 2]
selected_rows = arr[rows]
print("\n选择的第1行和第3行:")
print(selected_rows)

# 说明:使用索引列表选择特定元素
# 同时指定行索引和列索引
rows = [0, 2]  # 选择第 1 行和第 3 行
cols = [2, 0]  # 分别选择第 3 列和第 1 列
selected = arr[rows, cols]  # 选择 (0,2) 和 (2,0) 位置的元素
print("\n花式索引结果((0,2) 和 (2,0)):", selected)

# 说明:选择矩形区域
# 使用 np.ix_() 函数创建索引网格
rows = [0, 2]
cols = [0, 2]
grid = arr[np.ix_(rows, cols)]  # 选择 (0,0), (0,2), (2,0), (2,2)
print("\n使用 np.ix_() 选择的矩形区域:")
print(grid)

6. 数组操作 #

数组操作包括形状改变、拼接、拆分等,这些是数据预处理中常用的操作。

6.1 改变数组形状 #

方法 功能说明 常用参数 返回值
.reshape() 改变数组形状(返回视图) shape:新形状,如 (3, 4) 重塑后的数组
.flatten() 展平数组(返回副本) 无 一维数组(副本)
.ravel() 展平数组(返回视图) 无 一维数组(通常是视图)
arr[:, None] 增加维度(将行向量变为列向量) None:在指定位置添加新维度 增加维度后的数组
# -*- coding: utf-8 -*-
# 说明:演示如何改变数组的形状

# 说明:导入 NumPy 库
import numpy as np

# 说明:创建一维数组
vector = np.arange(12)
print("原始一维数组:", vector)
print(f"形状:{vector.shape}")

# 说明:重塑为二维数组
# reshape() 方法改变数组的形状
# 参数 (3, 4) 表示重塑为 3 行 4 列
# 注意:新形状的元素总数必须与原数组相同(12 = 3 * 4)
matrix = vector.reshape(3, 4)
print("\n重塑为 3x4 矩阵:")
print(matrix)
print(f"形状:{matrix.shape}")

# 说明:展平数组(变回一维)
# flatten() 方法返回一个展平后的副本(不影响原数组)
flat1 = matrix.flatten()
print("\nflatten() 展平(返回副本):", flat1)

# 说明:ravel() 方法也可以展平(通常返回视图,可能影响原数组)
flat2 = matrix.ravel()
print("ravel() 展平(可能返回视图):", flat2)

# 说明:改变数组的维度数
# 使用 None 或 np.newaxis 增加维度
row_vec = np.array([1, 2, 3])
col_vec = row_vec[:, None]  # 变为列向量(2 维)
print(f"\n原数组:{row_vec}, 形状:{row_vec.shape}")
print(f"列向量:\n{col_vec}, 形状:{col_vec.shape}")

6.2 拼接数组 #

方法 功能说明 常用参数 返回值
np.vstack() 垂直拼接(按行拼接,行数增加) tup:要拼接的数组元组或列表 垂直拼接后的数组
np.hstack() 水平拼接(按列拼接,列数增加) tup:要拼接的数组元组或列表 水平拼接后的数组
np.concatenate() 通用拼接函数 arrays:要拼接的数组列表,axis:拼接的轴(0=行,1=列) 拼接后的数组
# -*- coding: utf-8 -*-
# 说明:演示如何拼接数组

# 说明:导入 NumPy 库
import numpy as np

# 说明:创建两个示例数组
a = np.array([[1, 2], [3, 4]])
b = np.array([[5, 6], [7, 8]])
print("数组 a:")
print(a)
print("\n数组 b:")
print(b)

# 说明:垂直拼接(按行拼接)
# vstack() 函数将数组垂直堆叠
# 结果的行数增加
vertical = np.vstack([a, b])
print("\n垂直拼接(按行):")
print(vertical)

# 说明:水平拼接(按列拼接)
# hstack() 函数将数组水平堆叠
# 结果的列数增加
horizontal = np.hstack([a, b])
print("\n水平拼接(按列):")
print(horizontal)

# 说明:通用拼接函数
# concatenate() 函数可以指定拼接的轴(axis)
# axis=0 表示按行拼接(垂直),axis=1 表示按列拼接(水平)
concatenated = np.concatenate([a, b], axis=0)
print("\n使用 concatenate() 垂直拼接:")
print(concatenated)

6.3 拆分数组 #

方法 功能说明 常用参数 返回值
np.hsplit() 水平拆分(按列拆分) ary:要拆分的数组,indices:拆分点或部分数 拆分后的数组列表
np.vsplit() 垂直拆分(按行拆分) ary:要拆分的数组,indices:拆分点或部分数 拆分后的数组列表
np.split() 通用拆分函数 ary:要拆分的数组,indices_or_sections:拆分点,axis:拆分的轴 拆分后的数组列表
# -*- coding: utf-8 -*-
# 说明:演示如何拆分数组

# 说明:导入 NumPy 库
import numpy as np

# 说明:创建一个示例数组
arr = np.arange(12).reshape(3, 4)
print("原始数组:")
print(arr)

# 说明:水平拆分(按列拆分)
# hsplit() 函数将数组水平拆分成多个子数组
# 参数 2 表示拆分成 2 个部分
parts = np.hsplit(arr, 2)
print("\n水平拆分成 2 部分:")
for i, part in enumerate(parts):
    print(f"第 {i+1} 部分:")
    print(part)

# 说明:垂直拆分(按行拆分)
# vsplit() 函数将数组垂直拆分成多个子数组
parts = np.vsplit(arr, 3)
print("\n垂直拆分成 3 部分:")
for i, part in enumerate(parts):
    print(f"第 {i+1} 部分:")
    print(part)

# 说明:通用拆分函数
# split() 函数可以指定拆分的轴
parts = np.split(arr, 3, axis=0)  # 按行拆分
print("\n使用 split() 按行拆分:")
for i, part in enumerate(parts):
    print(f"第 {i+1} 部分:")
    print(part)

7. 数学运算 #

NumPy 提供了丰富的数学运算函数,支持向量化计算(对整个数组进行计算)。

7.1 基本运算 #

本代码块中使用的 NumPy 操作:

操作 功能说明 示例 返回值
arr1 + arr2 向量化加法(对应元素相加) a + b 相加后的数组
arr1 - arr2 向量化减法(对应元素相减) b - a 相减后的数组
arr1 * arr2 向量化乘法(对应元素相乘,不是矩阵乘法) a * b 相乘后的数组
arr1 / arr2 向量化除法(对应元素相除) b / a 相除后的数组
arr ** n 幂运算(每个元素的 n 次方) a ** 2 幂运算后的数组
arr + scalar 标量与数组运算(广播) a + 10 每个元素都加上标量的数组
arr * scalar 标量与数组运算(广播) a * 2 每个元素都乘以标量的数组
# -*- coding: utf-8 -*-
# 说明:演示基本的数学运算

# 说明:导入 NumPy 库
import numpy as np

# 说明:创建两个示例数组
a = np.array([1, 2, 3, 4])
b = np.array([5, 6, 7, 8])

print("数组 a:", a)
print("数组 b:", b)

# 说明:向量化加法(对应元素相加)
# NumPy 可以直接对数组进行数学运算,不需要循环
add_result = a + b
print("\n加法(a + b):", add_result)

# 说明:向量化减法
sub_result = b - a
print("减法(b - a):", sub_result)

# 说明:向量化乘法(对应元素相乘,不是矩阵乘法)
mult_result = a * b
print("乘法(a * b,对应元素相乘):", mult_result)

# 说明:向量化除法
div_result = b / a
print("除法(b / a):", div_result)

# 说明:幂运算
power_result = a ** 2
print("幂运算(a 的平方):", power_result)

# 说明:标量与数组的运算(广播)
# NumPy 会自动将标量广播到数组的每个元素
scalar_add = a + 10
print("\n标量加法(a + 10):", scalar_add)

scalar_mult = a * 2
print("标量乘法(a * 2):", scalar_mult)

7.2 数学函数 #

NumPy 提供了丰富的数学函数。

方法 功能说明 常用参数 返回值
np.sin() 计算正弦值 x:角度(弧度) 正弦值数组
np.cos() 计算余弦值 x:角度(弧度) 余弦值数组
np.tan() 计算正切值 x:角度(弧度) 正切值数组
np.exp() 计算 e 的 x 次方 x:指数 e^x 数组
np.log() 计算自然对数(以 e 为底) x:真数 自然对数数组
np.log10() 计算以 10 为底的对数 x:真数 常用对数数组
np.sqrt() 计算平方根 x:被开方数 平方根数组
np.cbrt() 计算立方根 x:被开方数 立方根数组
np.abs() 计算绝对值 x:数值 绝对值数组
np.floor() 向下取整 x:浮点数 向下取整后的数组
np.ceil() 向上取整 x:浮点数 向上取整后的数组
np.round() 四舍五入 x:浮点数 四舍五入后的数组
np.pi 圆周率常量 无(常量) 3.14159...
# -*- coding: utf-8 -*-
# 说明:演示 NumPy 的数学函数

# 说明:导入 NumPy 库
import numpy as np

# 说明:创建示例数组
arr = np.array([1, 2, 3, 4])

# 说明:三角函数
angles = np.array([0, np.pi/4, np.pi/2])
print("角度(弧度):", angles)
print("sin值:", np.sin(angles))
print("cos值:", np.cos(angles))
print("tan值:", np.tan(angles))

# 说明:指数和对数
print("\n指数运算(e的x次方):", np.exp(arr))
print("自然对数:", np.log(arr))
print("以10为底的对数:", np.log10(arr))

# 说明:开方和幂
print("\n平方根:", np.sqrt(arr))
print("立方根:", np.cbrt(arr))

# 说明:绝对值
neg_arr = np.array([-1, -2, 3, -4])
print("\n绝对值:", np.abs(neg_arr))

# 说明:向上取整和向下取整
float_arr = np.array([1.2, 2.7, 3.5, 4.1])
print("\n向下取整:", np.floor(float_arr))
print("向上取整:", np.ceil(float_arr))
print("四舍五入:", np.round(float_arr))

8. 统计函数 #

NumPy 提供了丰富的统计函数,可以计算均值、标准差、最大值、最小值等。

8.1 基本统计 #

方法 功能说明 常用参数 返回值
np.sum() 计算所有元素的总和 a:数组,axis:统计的轴(可选) 总和值
np.mean() 计算所有元素的平均值 a:数组,axis:统计的轴(可选) 平均值
np.std() 计算标准差(衡量数据离散程度) a:数组,axis:统计的轴(可选) 标准差
np.var() 计算方差(标准差的平方) a:数组,axis:统计的轴(可选) 方差
np.max() 找出最大值 a:数组,axis:统计的轴(可选) 最大值
np.min() 找出最小值 a:数组,axis:统计的轴(可选) 最小值
np.argmax() 找出最大值的索引 a:数组,axis:统计的轴(可选) 最大值的索引
np.argmin() 找出最小值的索引 a:数组,axis:统计的轴(可选) 最小值的索引
# -*- coding: utf-8 -*-
# 说明:演示 NumPy 的统计函数

# 说明:导入 NumPy 库
import numpy as np

# 说明:创建一个示例矩阵
matrix = np.arange(1, 10).reshape(3, 3)
print("示例矩阵:")
print(matrix)

# 说明:计算总和
# sum() 函数计算所有元素的总和
total = np.sum(matrix)
print(f"\n总和:{total}")

# 说明:计算均值
# mean() 函数计算所有元素的平均值
average = np.mean(matrix)
print(f"均值:{average:.2f}")

# 说明:计算标准差
# std() 函数计算标准差(衡量数据的离散程度)
std_dev = np.std(matrix)
print(f"标准差:{std_dev:.2f}")

# 说明:计算方差
# var() 函数计算方差(标准差的平方)
variance = np.var(matrix)
print(f"方差:{variance:.2f}")

# 说明:找出最大值和最小值
max_value = np.max(matrix)
min_value = np.min(matrix)
print(f"\n最大值:{max_value}")
print(f"最小值:{min_value}")

# 说明:找出最大值和最小值的索引
max_index = np.argmax(matrix)
min_index = np.argmin(matrix)
print(f"最大值的索引(展平后):{max_index}")
print(f"最小值的索引(展平后):{min_index}")

8.2 按轴统计 #

在多维数组中,可以指定统计的轴(维度)。

方法 功能说明 参数说明 返回值
np.mean(axis=0) 沿行方向统计(计算每列的均值) axis=0:沿行方向 每列均值的数组
np.mean(axis=1) 沿列方向统计(计算每行的均值) axis=1:沿列方向 每行均值的数组
np.sum(axis=0) 沿行方向统计(计算每列的总和) axis=0:沿行方向 每列总和的数组
np.sum(axis=1) 沿列方向统计(计算每行的总和) axis=1:沿列方向 每行总和的数组
# -*- coding: utf-8 -*-
# 说明:演示按轴进行统计(沿特定维度)

# 说明:导入 NumPy 库
import numpy as np

# 说明:创建一个 3x4 的矩阵
matrix = np.arange(12).reshape(3, 4)
print("示例矩阵(3行4列):")
print(matrix)

# 说明:按行统计(axis=0,计算每列)
# axis=0 表示沿着行方向(垂直方向)统计
column_mean = np.mean(matrix, axis=0)
print("\n每列的平均值(axis=0):", column_mean)

column_sum = np.sum(matrix, axis=0)
print("每列的总和(axis=0):", column_sum)

# 说明:按列统计(axis=1,计算每行)
# axis=1 表示沿着列方向(水平方向)统计
row_mean = np.mean(matrix, axis=1)
print("\n每行的平均值(axis=1):", row_mean)

row_sum = np.sum(matrix, axis=1)
print("每行的总和(axis=1):", row_sum)

# 说明:不指定轴(计算所有元素)
all_mean = np.mean(matrix)
print(f"\n所有元素的平均值(不指定轴):{all_mean}")

9. 随机数 #

NumPy 的 random 模块提供了生成随机数的功能,常用于模拟、采样、数据增强等场景。

9.1 基本随机数生成 #

方法 功能说明 常用参数 返回值
np.random.seed() 设置随机种子(确保结果可复现) seed:种子值 无
np.random.rand() 生成 [0, 1) 区间的均匀分布随机数 *d0, d1, ...:各维度大小 均匀分布随机数组
np.random.randn() 生成标准正态分布随机数(均值0,标准差1) *d0, d1, ...:各维度大小 标准正态分布随机数组
np.random.randint() 生成指定区间的整数随机数 low:最小值,high:最大值(不包含),size:大小 整数随机数组
np.random.normal() 生成正态分布随机数 loc:均值,scale:标准差,size:大小 正态分布随机数组
# -*- coding: utf-8 -*-
# 说明:演示 NumPy 的随机数生成

# 说明:导入 NumPy 库
import numpy as np

# 说明:设置随机种子(确保结果可复现)
# 设置相同的种子,每次运行会得到相同的随机数
np.random.seed(42)

# 说明:生成均匀分布的随机数
# rand() 函数生成 [0, 1) 区间的均匀分布随机数
# 参数 (2, 3) 表示生成一个 2 行 3 列的数组
uniform = np.random.rand(2, 3)
print("均匀分布随机数([0, 1) 区间):")
print(uniform)

# 说明:生成标准正态分布的随机数
# randn() 函数生成标准正态分布(均值为0,标准差为1)的随机数
normal = np.random.randn(2, 3)
print("\n标准正态分布随机数:")
print(normal)

# 说明:生成指定区间的整数随机数
# randint() 函数生成指定区间的整数随机数
# 参数:最小值(包含)、最大值(不包含)、大小
integers = np.random.randint(0, 10, size=(2, 3))
print("\n整数随机数(0-9):")
print(integers)

# 说明:生成指定分布和参数的随机数
# normal() 函数生成正态分布随机数
# 参数:均值、标准差、大小
custom_normal = np.random.normal(loc=100, scale=15, size=(2, 3))
print("\n自定义正态分布(均值100,标准差15):")
print(custom_normal)

9.2 随机选择与打乱 #

方法 功能说明 常用参数 返回值
np.random.choice() 从数组中随机选择元素 a:数组,size:选择数量,replace:是否允许重复 随机选择的元素数组
np.random.shuffle() 原地打乱数组(修改原数组) x:要打乱的数组 无(修改原数组)
np.random.permutation() 返回打乱后的新数组(不修改原数组) x:要打乱的数组 打乱后的新数组
# -*- coding: utf-8 -*-
# 说明:演示随机选择和打乱操作

# 说明:导入 NumPy 库
import numpy as np

# 说明:设置随机种子
np.random.seed(42)

# 说明:从数组中选择随机元素
# choice() 函数从数组中随机选择元素
# 参数:数组、选择数量、是否允许重复
choices = np.array(["A", "B", "C", "D"])
selected = np.random.choice(choices, size=5, replace=True)
print("从数组中选择 5 个元素(允许重复):", selected)

# 说明:随机打乱数组
# shuffle() 函数原地打乱数组(修改原数组)
arr = np.arange(10)
print("\n原始数组:", arr)
np.random.shuffle(arr)
print("打乱后:", arr)

# 说明:返回打乱后的新数组(不修改原数组)
arr2 = np.arange(10)
print("\n原始数组:", arr2)
shuffled = np.random.permutation(arr2)
print("打乱后的新数组:", shuffled)
print("原数组未改变:", arr2)

10. 文件操作 #

NumPy 可以方便地将数组保存到文件或从文件加载数组。

10.1 保存和加载 #

方法 功能说明 常用参数 返回值
np.random.randn() 生成标准正态分布随机数 *d0, d1, ...:各维度大小 标准正态分布随机数组
np.savetxt() 将数组保存为文本文件 fname:文件名,X:数组,fmt:格式,delimiter:分隔符 无
np.loadtxt() 从文本文件加载数组 fname:文件名,delimiter:分隔符 加载的数组
np.save() 将数组保存为二进制文件(.npy 格式) file:文件名,arr:数组 无
np.load() 从二进制文件加载数组(.npy 或 .npz 格式) file:文件名 加载的数组或字典
np.allclose() 检查两个数组是否近似相等 a:数组1,b:数组2 布尔值(True/False)
# -*- coding: utf-8 -*-
# 说明:演示如何保存和加载 NumPy 数组

# 说明:导入 NumPy 库
import numpy as np
import os

# 说明:创建示例数据
data = np.random.randn(5, 3)
print("原始数据:")
print(data)

# 说明:保存为文本文件
# savetxt() 函数将数组保存为文本文件
# 参数:文件名、数据、格式、分隔符
np.savetxt("data.txt", data, fmt="%.4f", delimiter=",")
print("\n数据已保存到 data.txt")

# 说明:从文本文件加载
# loadtxt() 函数从文本文件加载数组
loaded_txt = np.loadtxt("data.txt", delimiter=",")
print("\n从文本文件加载的数据:")
print(loaded_txt)

# 说明:保存为二进制文件(推荐,更快更小)
# save() 函数将数组保存为 .npy 格式(NumPy 二进制格式)
np.save("data.npy", data)
print("\n数据已保存到 data.npy")

# 说明:从二进制文件加载
# load() 函数从 .npy 文件加载数组
loaded_npy = np.load("data.npy")
print("\n从二进制文件加载的数据:")
print(loaded_npy)

# 说明:验证数据是否一致
if np.allclose(data, loaded_npy):
    print("\n✓ 数据加载成功,与原始数据一致")

# 说明:清理临时文件(可选)
if os.path.exists("data.txt"):
    os.remove("data.txt")
if os.path.exists("data.npy"):
    os.remove("data.npy")

10.2 批量保存和加载 #

方法 功能说明 常用参数 返回值
np.savez() 将多个数组保存到一个压缩文件(.npz 格式) file:文件名,**kwds:关键字参数(数组名称=数组) 无
np.load() 加载 .npz 文件,返回类似字典的对象 file:文件名 类似字典的对象,可用键访问数组
# -*- coding: utf-8 -*-
# 说明:演示如何批量保存和加载多个数组

# 说明:导入 NumPy 库
import numpy as np
import os

# 说明:创建多个数组
arr1 = np.array([1, 2, 3])
arr2 = np.array([[4, 5], [6, 7]])
arr3 = np.array([8, 9, 10])

# 说明:批量保存多个数组
# savez() 函数将多个数组保存到一个压缩文件
# 使用关键字参数指定每个数组的名称
np.savez("multiple_arrays.npz", array1=arr1, array2=arr2, array3=arr3)
print("多个数组已保存到 multiple_arrays.npz")

# 说明:从压缩文件加载
# load() 函数加载 .npz 文件,返回一个类似字典的对象
loaded = np.load("multiple_arrays.npz")
print("\n加载的数组:")
print("array1:", loaded["array1"])
print("array2:")
print(loaded["array2"])
print("array3:", loaded["array3"])

# 说明:查看文件中包含的所有数组名称
print("\n文件中包含的数组名称:", list(loaded.keys()))

# 说明:清理临时文件(可选)
if os.path.exists("multiple_arrays.npz"):
    os.remove("multiple_arrays.npz")

11. 实战案例:销售数据分析 #

下面是一个完整的实战案例,展示如何使用 NumPy 分析销售数据。

方法 功能说明 常用参数 返回值
np.random.normal() 生成正态分布随机数 loc:均值,scale:标准差,size:大小 正态分布随机数组
.astype() 转换数组的数据类型 dtype:目标数据类型,如 int 转换类型后的数组
.sum(axis=0) 沿行方向求和(计算每列总和) axis=0:沿行方向 每列总和的数组
.sum(axis=1) 沿列方向求和(计算每行总和) axis=1:沿列方向 每行总和的数组
.mean(axis=0) 沿行方向求均值(计算每列均值) axis=0:沿行方向 每列均值的数组
np.diff() 计算相邻元素的差值 a:数组 差值数组(长度比原数组少1)
np.argmax() 找出最大值的索引 a:数组,axis:统计的轴(可选) 最大值的索引
# -*- coding: utf-8 -*-
# 说明:实战案例 - 销售数据分析
# 演示如何使用 NumPy 分析模拟的销售数据

# 说明:导入 NumPy 库
import numpy as np

# 说明:设置随机种子,确保结果可复现
np.random.seed(0)

# 说明:生成模拟的销售数据
# 生成 12 个月 × 4 个产品的销售数据
# normal() 生成正态分布随机数:均值 1000,标准差 200
# astype(int) 将浮点数转换为整数
sales = np.random.normal(loc=1000, scale=200, size=(12, 4)).astype(int)
products = np.array(["产品A", "产品B", "产品C", "产品D"])

# 说明:打印原始数据
print("月度销量矩阵(12个月 × 4个产品):")
print(sales)
print(f"形状:{sales.shape}\n")

# 说明:计算每个产品的总销售额
# sum(axis=0) 计算每列的总和(每个产品的全年总销售额)
total_by_product = sales.sum(axis=0)
print("每个产品的全年总销售额:")
for prod, total in zip(products, total_by_product):
    print(f"  {prod}:{total:,}")

# 说明:计算每个产品的平均月销售额
avg_by_product = sales.mean(axis=0)
print("\n每个产品的平均月销售额:")
for prod, avg in zip(products, avg_by_product):
    print(f"  {prod}:{avg:.2f}")

# 说明:计算每个月的总销售额
# sum(axis=1) 计算每行的总和(每个月的总销售额)
monthly_total = sales.sum(axis=1)
print(f"\n每个月的总销售额:{monthly_total}")

# 说明:计算月度增长率
# diff() 函数计算相邻元素的差值
# 计算增长率:差值 / 上月的销售额 * 100
growth = np.diff(monthly_total) / monthly_total[:-1] * 100
print("\n月度增长率(%):")
for i, g in enumerate(growth, 1):
    print(f"  第{i}月到第{i+1}月:{g:.2f}%")

# 说明:找出销售最好的月份和产品
best_month_idx = np.argmax(monthly_total)
best_month_sales = monthly_total[best_month_idx]
print(f"\n销售最好的月份:第{best_month_idx + 1}月,销售额:{best_month_sales:,}")

# 说明:找出每个产品销量最好的月份
print("\n每个产品销量最好的月份:")
for i, prod in enumerate(products):
    best_month = np.argmax(sales[:, i]) + 1  # +1 因为月份从1开始
    best_sales = sales[best_month - 1, i]
    print(f"  {prod}:第{best_month}月,销量:{best_sales:,}")

12. 性能优化与常见问题 #

在使用 NumPy 时,了解一些优化技巧和常见问题有助于提高代码效率。

12.1 向量化 vs 循环 #

NumPy 的向量化计算比 Python 循环快得多。

方法 功能说明 常用参数 返回值
np.random.rand() 生成 [0, 1) 区间的均匀分布随机数 *d0, d1, ...:各维度大小 均匀分布随机数组
arr * arr 向量化乘法(对应元素相乘) 两个数组 相乘后的数组
np.allclose() 检查两个数组是否近似相等 a:数组1,b:数组2 布尔值(True/False)
# -*- coding: utf-8 -*-
# 说明:演示向量化计算与循环的性能对比

# 说明:导入必要的库
import numpy as np
import time

# 说明:创建一个大型数组
arr = np.random.rand(1_000_000)  # 100 万个元素

# 说明:方法1:使用 Python 循环
# 这是慢的方法,逐个元素计算
start = time.time()
loop_result = np.array([x * x for x in arr])
loop_time = time.time() - start

# 说明:方法2:使用 NumPy 向量化
# 这是快的方法,对整个数组进行运算
start = time.time()
np_result = arr * arr
np_time = time.time() - start

# 说明:比较结果
print(f"Python 循环耗时:{loop_time:.4f} 秒")
print(f"NumPy 向量化耗时:{np_time:.4f} 秒")
print(f"速度提升:{loop_time / np_time:.1f} 倍")

# 说明:验证结果是否一致
if np.allclose(loop_result, np_result):
    print("\n✓ 两种方法结果一致,但向量化更快")

12.2 数据类型选择 #

合理选择数据类型可以节省内存。

本代码块中使用的 NumPy 方法和属性:

方法/属性 功能说明 常用参数 返回值
np.array(..., dtype=...) 创建指定数据类型的数组 object:数据,dtype:数据类型 指定类型的数组
.dtype 获取数组的数据类型 无(属性) 数据类型对象
.nbytes 获取数组占用的总字节数 无(属性) 总字节数(整数)
.astype() 转换数组的数据类型 dtype:目标数据类型 转换类型后的数组
# -*- coding: utf-8 -*-
# 说明:演示数据类型对内存的影响

# 说明:导入 NumPy 库
import numpy as np

# 说明:创建相同数据的数组,但使用不同的数据类型
arr_int32 = np.array([1, 2, 3, 4], dtype=np.int32)
arr_int64 = np.array([1, 2, 3, 4], dtype=np.int64)
arr_float64 = np.array([1, 2, 3, 4], dtype=np.float64)

# 说明:查看每个数组的内存占用
print(f"int32 数组大小:{arr_int32.nbytes} 字节")
print(f"int64 数组大小:{arr_int64.nbytes} 字节")
print(f"float64 数组大小:{arr_float64.nbytes} 字节")

# 说明:查看数据类型
print(f"\nint32 数据类型:{arr_int32.dtype}")
print(f"int64 数据类型:{arr_int64.dtype}")
print(f"float64 数据类型:{arr_float64.dtype}")

# 说明:转换数据类型
# astype() 方法可以转换数组的数据类型
arr_float = arr_int32.astype(np.float32)
print(f"\n转换为 float32:{arr_float.dtype}")

12.3 广播机制 #

广播机制允许不同形状的数组进行运算。

本代码块中使用的 NumPy 方法和操作:

方法/操作 功能说明 常用参数 返回值
np.arange() 创建等差数列 start:起始值,stop:结束值(不包含) 等差数列
.reshape() 改变数组形状 shape:新形状 重塑后的数组
arr1 + arr2 数组加法(支持广播) 两个数组(形状可不同,但需兼容) 相加后的数组
arr + scalar 数组与标量相加(广播) arr:数组,scalar:标量 每个元素都加上标量的数组
# -*- coding: utf-8 -*-
# 说明:演示 NumPy 的广播机制

# 说明:导入 NumPy 库
import numpy as np

# 说明:创建一个矩阵和一个向量
matrix = np.arange(12).reshape(3, 4)
vector = np.array([10, 20, 30, 40])

print("矩阵:")
print(matrix)
print(f"\n向量:{vector}")
print(f"向量形状:{vector.shape}")

# 说明:广播:向量会自动扩展以匹配矩阵的形状
# 这里向量会扩展为 3x4 矩阵,每一行都是 [10, 20, 30, 40]
result = matrix + vector
print("\n矩阵 + 向量(广播):")
print(result)

# 说明:标量广播
scalar = 100
result2 = matrix + scalar
print("\n矩阵 + 标量(广播):")
print(result2)

12.4 常见问题 #

本代码块中使用的 NumPy 方法和操作:

方法/操作 功能说明 常用参数 返回值
arr[start:end] 切片操作(返回视图) start:起始索引,end:结束索引 切片数组(视图)
.copy() 创建数组的副本 无 数组的独立副本
arr1 + arr2 数组加法(广播) 两个数组 相加后的数组
arr / scalar 数组除法(自动转换为浮点数) arr:数组,scalar:标量 相除后的数组(浮点型)
# -*- coding: utf-8 -*-
# 说明:常见问题和解决方案

# 说明:导入 NumPy 库
import numpy as np

# 说明:问题1:修改数组时的视图 vs 副本
print("问题1:视图 vs 副本")
arr = np.array([1, 2, 3, 4, 5])
view = arr[1:4]  # 这是视图(引用)
view[0] = 999    # 修改视图会影响原数组
print(f"原数组被修改:{arr}")

arr2 = np.array([1, 2, 3, 4, 5])
copy = arr2[1:4].copy()  # 这是副本(独立)
copy[0] = 999
print(f"原数组未改变:{arr2}")

# 说明:问题2:数组形状不匹配
print("\n问题2:形状不匹配时的处理")
a = np.array([[1, 2], [3, 4]])
b = np.array([5, 6])
try:
    # 这可能会出错,因为形状不匹配
    result = a + b
    print("运算成功(广播):")
    print(result)
except Exception as e:
    print(f"错误:{e}")

# 说明:问题3:整数除法的陷阱
print("\n问题3:整数除法的结果")
arr = np.array([1, 2, 3, 4])
result = arr / 2  # 即使原数组是整数,结果也是浮点数
print(f"整数数组除以2:{result}, 类型:{result.dtype}")

13. 学习资源 #

  • NumPy 官方文档
  • NumPy 快速入门

访问验证

请输入访问令牌

Token不正确,请重新输入