文章目录
- 一、简介
- 二、 ndarray 对象
- 三、矩阵拼接
- 四、数值运算
- 4.1 数值选取
- 4.2 单个数组的运算
- 4.21 NumPy定义的常量
- 4.22 单数组运算
- 4.3 数组之间的运算
- 4.31 常见运算
- 🟢4.32 广播机制:Broadcasting
- 五、数值类型、类型转换
- 六、文件I/O
一、简介
NumPy 是一个用于科学计算的 Python 库。它提供了对大型多维数组和矩阵的支持,此外还提供了许多高级数学函数来操作这些数组。NumPy 是许多其他科学计算和数据分析库的基础,比如 SciPy、Pandas 和 TensorFlow。
Github:https://github.com/numpy/numpy
User Guide:https://numpy.org/doc/2.0/user/index.html#user
数值计算、多维数组操作。
核心功能:
-
ndarray 对象:
- NumPy 的核心是 ndarray 对象,它是一个多维数组,具有同质数据类型(数组中元素是同种类型)。所有元素在内存中是连续存储的,因此可以高效地进行计算。
- 可以通过
numpy.array
函数创建 ndarray 对象。
-
数组创建:
numpy.array
:从普通的 Python 列表或元组创建数组。numpy.zeros
:创建全零数组。numpy.ones
:创建全一数组。numpy.arange
:创建范围数组,类似于 Python 内置的range
函数。numpy.linspace
:创建线性间隔的数组。
-
数组操作:
- 索引和切片:类似于 Python 列表的操作,但可以用于多维数组。
- 形状操作:
reshape
、flatten
、transpose
等函数可以改变数组的形状。 - 数组计算:支持元素级运算、矩阵运算、广播机制等。
-
数学函数:
- NumPy 提供了一系列常用的数学函数,如
sum
、mean
、std
、max
、min
等。 - 还包括许多高级数学函数,如线性代数、傅里叶变换、随机数生成等。
- NumPy 提供了一系列常用的数学函数,如
优点:
- 高效计算:NumPy 使用 C 语言编写,其底层操作非常高效,可以处理大型数据集。
- 多维数组:支持多维数组和矩阵操作,非常适合线性代数计算。
- 丰富的函数库:提供了丰富的数学函数,可以满足科学计算的需求。
- 兼容性:与许多其他科学计算库(如 SciPy、Pandas)无缝集成。
应用场景:
- 数据分析:NumPy 是数据分析的基础工具,Pandas 就是建立在 NumPy 之上的。
- 机器学习:许多机器学习库(如 TensorFlow 和 PyTorch)都使用 NumPy 作为底层数据结构。
- 科学计算:在物理、化学、工程等领域,NumPy 是进行科学计算和建模的基础工具。
二、 ndarray 对象
NumPy 的 ndarray
对象是其核心数据结构,它是一个多维数组,支持高效的数值计算和各种科学计算操作。以下是对 ndarray
对象的详细介绍:
ndarray 对象的属性:
- ndim:数组的维数(即轴的个数)。
- shape:数组的形状,表示每个维度的大小,是一个元组。
- size:数组中所有元素的总数。
- dtype:数组元素的数据类型。
- itemsize:数组中每个元素的字节大小。
- nbytes:数组中所有元素所占的字节总数。
创建 ndarray:
可以通过多种方式创建 ndarray
对象:
(1) 从列表或元组创建:
import numpy as np
a = np.array([1, 2, 3])
b = np.array([[1, 2, 3], [4, 5, 6]])
(2) 使用 NumPy 内置函数:
# 创建全零数组
zeros_array = np.zeros((2, 3))
# 创建全一数组
ones_array = np.ones((3, 4))
# 创建给定形状的空数组(内容随机,未初始化)
empty_array = np.empty((2, 2))
# 创建线性间隔数组,5表示元素个数(不是步长)
linspace_array = np.linspace(0, 10, 5)
# 取对数后等距插值,依然是元素个数,不是步长
log_array = np,logspace(0,2,5)
# 创建范围数组,左闭右开,步长2,默认1,
arange_array = np.arange(0, 10, 2)
更多方法:
函数 | 描述 | 示例 |
---|---|---|
np.zeros | 创建全零数组,指定形状 | np.zeros((2, 3)) |
np.ones | 创建全一数组,指定形状 | np.ones((3, 4)) |
np.empty | 创建未初始化的数组(内容随机),指定形状 | np.empty((2, 2)) |
np.full | 创建一个用指定值填充的数组,指定形状 | np.full((2, 2), 7) |
np.eye | 创建单位矩阵,指定维度 | np.eye(3) |
np.identity | 创建单位矩阵,指定维度 | np.identity(3) |
np.arange | 创建一个范围数组,并可以通过 reshape 改变其形状 | np.arange(6).reshape((2, 3)) |
np.linspace | 创建线性间隔的数组,并可以通过 reshape 改变其形状 | np.linspace(0, 10, 6).reshape((2, 3)) |
np.logspace | 创建对数间隔的数组,并可以通过 reshape 改变其形状 | np.logspace(0, 2, 6).reshape((2, 3)) |
np.random.rand | 创建一个均匀分布的随机数组,指定形状 | np.random.rand(3, 2) |
np.random.randn | 创建一个标准正态分布的随机数组,指定形状 | np.random.randn(3, 2) |
np.random.randint | 创建一个给定范围内的随机整数数组,指定形状 | np.random.randint(0, 10, (3, 3)) |
np.fromfunction | 通过一个函数生成数组,指定形状 | np.fromfunction(lambda i, j: i + j, (3, 3)) |
np.fromiter | 从可迭代对象生成数组,并可以通过 reshape 改变其形状 | np.fromiter(range(6), dtype=int).reshape((2, 3)) |
np.meshgrid | 从坐标向量生成网格矩阵 | np.meshgrid(np.arange(3), np.arange(3)) |
np.reshape | 改变已有数组的形状 | np.arange(6).reshape((2, 3)) |
np.transpose | 转置数组 | np.transpose(np.arange(6).reshape((2, 3))) |
np.expand_dims | 扩展数组的维度 | np.expand_dims(np.array([1, 2, 3]), axis=0) |
np.squeeze | 去除数组中为 1 的维度 | np.squeeze(np.array([[[1, 2, 3]]])) |
np.concatenate | 沿指定轴连接数组 | np.concatenate((np.zeros((2, 2)), np.ones((2, 2))), axis=1) |
np.hstack | 水平堆叠数组 | np.hstack((np.zeros((2, 2)), np.ones((2, 2)))) |
np.vstack | 垂直堆叠数组 | np.vstack((np.zeros((2, 2)), np.ones((2, 2)))) |
np.split | 将数组分割成多个子数组 | np.split(np.arange(6).reshape((2, 3)), 2, axis=1) |
np.hsplit | 水平分割数组 | np.hsplit(np.arange(6).reshape((2, 3)), 3) |
np.vsplit | 垂直分割数组 | np.vsplit(np.arange(6).reshape((2, 3)), 2) |
三、矩阵拼接
方法 | 描述 | 示例 |
---|---|---|
np.concatenate | 沿指定轴连接数组 ,0竖着拼,1横着拼 | np.concatenate((a, b), axis=0) |
np.vstack | 垂直(行)堆叠数组,相当于沿轴 0 连接 | np.vstack((a, b)) |
np.hstack | 水平(列)堆叠数组,相当于沿轴 1 连接 | np.hstack((a, b)) |
np.dstack | 深度(第三维度)堆叠数组 | np.dstack((a, b)) |
np.stack | 沿新轴连接数组 | np.stack((a, b), axis=0) |
np.block | 创建一个新数组,通过将块状数组拼接在一起 | np.block([[a, b], [c, d]]) |
np.column_stack | 将 1D 数组作为列堆叠成 2D 数组 | np.column_stack((a, b)) |
np.row_stack | 将 1D 数组作为行堆叠成 2D 数组 | np.row_stack((a, b)) |
四、数值运算
4.1 数值选取
注意python的区间基本都是左闭右开的。 (右端点即长度,无缝拼接,一致性)
(1)简单索引和切片(和matlab类似的):
import numpy as np
a = np.array([1, 2, 3, 4, 5])
print(a[2]) # 输出: 3
print(a[1:4]) # 输出: [2, 3, 4]
print(a[::2]) # 输出: [1, 3, 5]
b = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
print(b[1, 2]) # 输出: 6
print(b[0:2, 1:3]) # 输出: [[2, 3], [5, 6]]
# 下面[0,2]指的是索引为0和2,这是个列表,不是区间
print(b[[0, 2], [0, 2]]) # 输出:[1 9]
# 这相当于两步操作,从b选择第1,3行,再从结果中选择1,3列
print(b[[0, 2], :][:, [0, 2]]) #输出:[[1,3][7,9]]
c = np.array([[[0, 1, 2], [3, 4, 5]], [[6, 7, 8], [9, 10, 11]]])
print(c[1, :, 2]) # 输出: [8, 11]
print(c[:, 1, :]) # 输出: [[3, 4, 5], [9, 10, 11]]
(2) 布尔索引:
print(a[a > 2]) # 输出: [3, 4, 5]
print(b[b > 5]) # 输出: [6, 7, 8, 9]
(3)整数数组索引:
indices = [0, 2, 4]
print(a[indices]) # 输出: [1, 3, 5]
row_indices = [0, 1, 2]
col_indices = [1, 0, 2]
print(b[row_indices, col_indices]) # 输出: [2, 4, 9]
(4)条件筛选:np.where
布尔索引就有点像这个。
np.where
是一个非常强大的函数,主要用于在数组中根据条件选择元素
或获取满足条件的元素的索引
。
a. 获取满足条件的元素的索引
import numpy as np
# 一维数组
a = np.array([10, 20, 30, 40, 50])
condition = a > 25
indices = np.where(condition)
print("满足条件的索引:", indices) # 输出: (array([2, 3, 4]),)
print("满足条件的元素:", a[indices]) # 输出: [30 40 50]
# 二维数组
b = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
condition = b > 5
indices = np.where(condition)
print("满足条件的行索引:", indices[0]) # 输出: [1 2 2 2 ]
print("满足条件的列索引:", indices[1]) # 输出: [2 0 1 2 ]
print("满足条件的元素:", b[indices]) # 输出: [6 7 8 9]
b. 从两个数组
中选择元素
根据条件生成的新数组,其中 condition 为 True 的位置取 x 中的值,为 False 的位置取 y 中的值。
下面例子:a>25为True的索引为:2,3,4;a>25为False为索引为:0,1。结果返回a索引为2、3、4的元素和b索引为0,1的元素。这两个数组形状必须一样,生成的数组也和它们形状一样。
import numpy as np
# 创建示例数组
a = np.array([10, 20, 30, 40, 50])
b = np.array([1, 2, 3, 4, 5])
condition = a > 25
# 根据条件选择元素
result = np.where(condition, a, b)
print("条件选择的结果:", result) # 输出: [ 1 2 30 40 50]
c. 条件替换
3个参数:条件,满足条件时取的值,不满足条件取的值。
import numpy as np
# 创建一个示例数组
c = np.array([1, 2, 3, 4, 5])
# 只保留满足条件的,其它的变成2倍
result = np.where(c < 3, c, 2 * c)
print("条件替换的结果:", result) # 输出[ 1 2 6 8 10]
# 条件为c<d,满足条件时,该位置为c的值,否则为d的值
# 即输出c、d对应位置的较小值
d = np.array([2, 1, 5, 5, 4])
result = np.where(c < d, c, d)
print(result) # 输出:[1 1 3 4 4]
空值和无穷值使用
np.isnan(arr)
和np.isinf(arr)
,而不是直接使用==
判断。
(5)条件筛选:np.argwhere
返回满足条件的元素的索引,输出格式为二维数组,即每一行都是一个满足条件的元素的索引,[x_index y_index]
这样。
对比:
import numpy as np
# 创建一个数组
arr = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
# 查找大于 5 的元素的索引
id1 = np.where(arr > 5)
id2 = np.argwhere(arr > 5)
# 打印索引
print("where的输出:", id1[0], id1[1])
print("argwhere的输出:\n", id2)
输出:
where的输出: [1 2 2 2] [2 0 1 2]
argwhere的输出:
[[1 2]
[2 0]
[2 1]
[2 2]]
4.2 单个数组的运算
4.21 NumPy定义的常量
NumPy 定义了许多常量,用于方便数值计算和操作:
常量 | 描述 |
---|---|
np.pi | 圆周率 (π) |
np.e | 自然对数的底数 (e) |
np.inf | 正无穷大 |
np.NINF | 负无穷大 |
np.nan | 非数 (Not a Number) |
np.NZERO | 非零的常量 (0) |
np.DT | 数据类型的标志,例如 np.int32 |
np.bool_ | 布尔类型的常量 |
np.int_ | 默认整型的常量 |
np.float_ | 默认浮点型的常量 |
np.complex_ | 默认复数型的常量 |
np.ndarray | NumPy 数组类型的常量 |
4.22 单数组运算
NumPy 中的基本算术运算都是对数组中的每个元素执行相同的操作
。这种操作被称为“逐元素操作”(element-wise operation)。
这与matlab中存在一些区别,matlab中逐个元素的乘、除、幂,前面要加一个点:.*
、./
、.^
。
运算 | 描述 | 示例代码 |
---|---|---|
基本算术运算 | ||
+ | 加法 | arr + 5 |
- | 减法 | arr - 5 |
* | 乘法 | arr * 2 |
/ | 除法 | arr / 2 |
** | 幂运算 | arr ** 2 |
np.sqrt() | 开平方 | np.sqrt(arr) |
np.exp() | 指数运算 | np.exp(arr) |
np.log() | 自然对数运算 | np.log(arr) |
np.log10() | 以10为底的对数运算 | np.log10(arr) |
np.abs() | 绝对值运算 | np.abs(arr) |
统计运算 | ||
np.sum() | 数组元素求和 | np.sum(arr) |
np.mean() | 数组元素平均值 | np.mean(arr) |
np.median() | 数组元素中位数 | np.median(arr) |
np.var() | 方差 | np.var(arr) |
np.std() | 标准差 | np.std(arr) |
np.min() | 最小值 | np.min(arr) |
np.max() | 最大值 | np.max(arr) |
逻辑运算 | ||
np.all() | 判断所有元素是否满足条件(返回布尔值) | np.all(arr > 0) |
np.any() | 判断是否有任何元素满足条件(返回布尔值) | np.any(arr > 0) |
np.where() | 条件选择 | np.where(arr > 0, arr, -1) |
累积运算 | ||
np.cumsum() | 累积和 | np.cumsum(arr) |
np.cumprod() | 累积积 | np.cumprod(arr) |
其他 | ||
np.power() | 幂运算 | np.power(arr,3 ) |
np.sin() | 取正弦 | np.sin(arr) |
很多操作参数中可以指定axis
,即轴,用于指定沿着哪个维度进行操作。0就是竖着来,1就是横着来。
- axis=0:沿着每列进行操作,如对每列求和。
- axis=1:沿着每行进行操作,如对每行求和。
矩阵运算:
🟢转置:将矩阵的行和列互换。
A = np.array([[1, 2, 3], [4, 5, 6]])
transpose_A = np.transpose(A)
# 或
transpose_A = A.T
print("转置矩阵:\n", transpose_A)
# 输出:
# [[1 4]
# [2 5]
# [3 6]]
🟢逆矩阵:对于方阵(即行数等于列数的矩阵),计算其逆矩阵。逆矩阵 A^(-1)
满足 A * A^(-1) = I
,其中 I
是单位矩阵。
from numpy.linalg import inv
A = np.array([[1, 2], [3, 4]])
inverse_A = inv(A)
print("逆矩阵:\n", inverse_A)
# 输出:
# [[-2. 1. ]
# [ 1.5 -0.5]]
🟢特征值和特征向量:用于矩阵分解。
from numpy.linalg import eig
A = np.array([[1, 2], [3, 4]])
eigenvalues, eigenvectors = eig(A)
print("特征值:", eigenvalues)
print("特征向量:\n", eigenvectors)
🟢矩阵的奇异值分解 (SVD):将矩阵分解为三个矩阵的乘积,通常用于数据降维和特征提取。
from numpy.linalg import svd
A = np.array([[1, 2], [3, 4]])
U, S, Vh = svd(A)
print("U:\n", U)
print("S:\n", S)
print("Vh:\n", Vh)
🟢矩阵的行列式:用于判断矩阵是否可逆以及其他属性。
from numpy.linalg import det
A = np.array([[1, 2], [3, 4]])
determinant_A = det(A)
print("行列式:", determinant_A)
# 输出: -2.0000000000000004
🟢矩阵的范数:用于测量矩阵的大小。
from numpy.linalg import norm
A = np.array([[1, 2], [3, 4]])
norm_A = norm(A)
print("矩阵的范数:", norm_A)
4.3 数组之间的运算
简单情况下就是线性代数学的矩阵之间的运算。
加减乘除
都是两个矩阵对应位置的元素进行运算。
4.31 常见运算
矩阵乘法、点积、转置、逆矩阵等
🟢矩阵乘法:使用 np.dot
或 @
符号进行矩阵乘法(即线性代数中的矩阵乘法)(*
是对应元素相乘)。
result_matmul = np.dot(A, B)
# 或
result_matmul = A @ B
print("矩阵乘法:\n", result_matmul)
# 输出:
# [[19 22]
# [43 50]]
🟢点积(内积):用于计算两个向量
的点积。
x = np.array([1, 2, 3])
y = np.array([4, 5, 6])
dot_product = np.dot(x, y)
print("点积:", dot_product)
# 输出: 32
🟢外积:对于一维数组(向量
),外积计算的是一个矩阵,其每个元素都是两个向量中对应元素的乘积。外积与内积不同,内积是一个标量,而外积是一个矩阵。
import numpy as np
x = np.array([1, 2, 3])
y = np.array([4, 5, 6])
outer_product = np.outer(x, y)
print("外积 (np.outer):\n", outer_product)
# 输出:
# [[ 4 5 6]
# [ 8 10 12]
# [12 15 18]]
🟢叉积:三维空间中的两个向量的运算。叉积的结果是一个新的向量,该向量垂直于原始的两个向量。
import numpy as np
a = np.array([1, 2, 3])
b = np.array([4, 5, 6])
cross_product = np.cross(a, b)
print("叉积 (np.cross):", cross_product)
# 输出: [-3 6 -3]
🟢4.32 广播机制:Broadcasting
NumPy 的广播(Broadcasting
)是一种强大的功能,用于在数组运算中处理不同形状的数组。广播机制允许 NumPy 在进行元素级运算时,对不同形状的数组进行自动对齐和扩展
,以便它们能够进行操作。广播使得数组运算更加灵活和高效。
广播的规则:
-
维度对齐:如果两个数组的维度(即轴数)不同,NumPy 会在较小的数组的维度上进行扩展,使其与较大的数组的维度对齐。
-
扩展规则:
- 如果两个数组的维度数量不同(比如一个是一维向量,一个是二维矩阵,维度分别为1和2),较小的数组会在
前面
补上1,(假如a的形状是(3,)
,b的形状是(3,1)
,那么a就会被补成(1,3)
,都变成2维了)直到两个数组的维度数量相同。 - 如果两个数组在某一维度上的长度不同,且其中一个长度为1(比如行数为1或者列数为1),则长度为1的数组会在该维度上扩展(即复制),使其与另一个数组的长度匹配。
- 如果两个数组在某一维度上的长度不同且都不为1,则无法进行广播,会抛出错误。
- 如果两个数组的维度数量不同(比如一个是一维向量,一个是二维矩阵,维度分别为1和2),较小的数组会在
感觉不像人话,简单来说就是:两个数组(形状是(3,)可以先补成(1,3)再比较)每个维度的长度必须相等,或者在不相等的时候其中一个数组在这个维度上的长度为1。
如:
a:
1 2 3
b:
1
2
3
计算: a + b
则a扩展为:
1 2 3
1 2 3
1 2 3
b扩展为:
1 1 1
2 2 2
3 3 3
而:
a:
1 2 3
b:
1 4
2 5
3 6
就不行,因为a的维度是1,先补1,shape变成(1,3),b的形状是(3,2),现在他们在第一个维度上不同且小的那个长度是1,但在第二个维度上也不同,小的那个却是2。不满足条件。
广播示例:
-
标量与数组运算:
标量(0维数组)与任意形状的数组运算时,标量会被广播到数组的形状上。
import numpy as np arr = np.array([1, 2, 3]) scalar = 2 result = arr + scalar print("标量与数组运算结果:", result) # 输出: [3 4 5]
这里,标量
2
被广播到arr
的每个元素上,执行逐元素加法。 -
不同形状的数组运算:
-
例 1:二维数组与一维数组
import numpy as np matrix = np.array([[1, 2, 3], [4, 5, 6]]) vector = np.array([10, 20, 30]) result = matrix + vector print("二维数组与一维数组运算结果:\n", result) # 输出: # [[11 22 33] # [14 25 36]]
在这个例子中,
vector
被广播到matrix
的每一行上。(Vector的) -
例 2:二维数组与形状为
(2, 1)
的二维数组import numpy as np matrix = np.array([[1, 2, 3], [4, 5, 6]]) column_vector = np.array([[10], [20]]) result = matrix + column_vector print("二维数组与列向量运算结果:\n", result) # 输出: # [[11 12 13] # [24 25 26]]
在这个例子中,
column_vector
被广播到matrix
的每一列上。
-
五、数值类型、类型转换
数据类型 | 描述 | 取值范围 | 示例 |
---|---|---|---|
整数类型 | |||
np.int8 | 8位有符号整数 | -128 到 127 | np.int8(5) |
np.int16 | 16位有符号整数 | -32,768 到 32,767 | np.int16(5000) |
np.int32 | 32位有符号整数 | -2,147,483,648 到 2,147,483,647 | np.int32(100000) |
np.int64 | 64位有符号整数 | -9,223,372,036,854,775,808 到 9,223,372,036,854,775,807 | np.int64(100000000000) |
无符号整数类型 | |||
np.uint8 | 8位无符号整数 | 0 到 255 | np.uint8(200) |
np.uint16 | 16位无符号整数 | 0 到 65,535 | np.uint16(50000) |
np.uint32 | 32位无符号整数 | 0 到 4,294,967,295 | np.uint32(1000000000) |
np.uint64 | 64位无符号整数 | 0 到 18,446,744,073,709,551,615 | np.uint64(10000000000000000000) |
浮点类型 | |||
np.float16 | 16位半精度浮点数 | ±6.10e-5 到 ±6.55e4 | np.float16(1.23) |
np.float32 | 32位单精度浮点数 | ±1.18e-38 到 ±3.40e38 | np.float32(1.234567) |
np.float64 | 64位双精度浮点数 | ±2.23e-308 到 ±1.79e308 | np.float64(1.2345678901234567) |
复数类型 | |||
np.complex64 | 64位复数(两个32位浮点数) | 实部和虚部分别是 ±3.40e38 | np.complex64(1 + 2j) |
np.complex128 | 128位复数(两个64位浮点数) | 实部和虚部分别是 ±1.79e308 | np.complex128(1 + 2j) |
布尔类型 | |||
np.bool_ | 布尔型 | True 或 False | np.bool_(True) |
字符串类型 | |||
np.str_ | 字符串 | 具体长度取决于实际数据 | np.str_('hello') |
类型转换是处理数据时常用的操作,可以通过 .astype()
方法将数组从一种数据类型转换为另一种数据类型,该方法返回一个新的数组,原数组保持不变。
import numpy as np
arr = np.array([1.5, 2.5, 3.5], dtype=np.float32)
arr_int = arr.astype(np.int32)
print(arr_int) # 输出: [1 2 3]
-
整数与浮点数
- 浮点数到整数:浮点数转换为整数时会丢失小数部分,并进行向下取整(即截断)。
- 整数到浮点数:整数转换为浮点数时会保留所有精度。
arr_float = np.array([1.9, 2.9, 3.9], dtype=np.float64) arr_int = arr_float.astype(np.int32) # 浮点数转换为整数 print(arr_int) # 输出: [1 2 3]
-
无符号整数与有符号整数
- 有符号整数到无符号整数:如果有符号整数的值是负数,转换为无符号整数时会进行模运算,结果可能不是预期的。
- 无符号整数到有符号整数:如果无符号整数的值超出了有符号整数的范围,可能会导致数据丢失或溢出。
arr_uint = np.array([255, 256], dtype=np.uint8) arr_int = arr_uint.astype(np.int16) # 无符号整数转换为有符号整数 print(arr_int) # 输出: [255 256]
-
布尔型与整数、浮点数
- 布尔型到整数:
True
转换为1
,False
转换为0
。 - 布尔型到浮点数:同样
True
转换为1.0
,False
转换为0.0
。
arr_bool = np.array([True, False, True], dtype=np.bool_) arr_int = arr_bool.astype(np.int32) # 布尔型转换为整数 print(arr_int) # 输出: [1 0 1]
- 布尔型到整数:
-
复数与实数
- 复数到实数:直接转换为实数会丢失虚部。
- 实数到复数:实数转换为复数时虚部为
0
。
arr_complex = np.array([1+2j, 3+4j], dtype=np.complex128) arr_real = arr_complex.astype(np.float64) # 复数转换为实数 print(arr_real) # 输出: [1. 3.]
-
字符串
- 字符串到数值:可以将表示数字的字符串转换为数值类型,但需要确保字符串的格式正确。
arr_str = np.array(['1.1', '2.2', '3.3'], dtype=np.str_) arr_float = arr_str.astype(np.float64) # 字符串转换为浮点数 print(arr_float) # 输出: [1.1 2.2 3.3]
注意事项:
-
数据丢失
类型转换时可能会导致数据丢失或精度降低。例如,将浮点数转换为整数会丢失小数部分,将大的整数转换为小的数据类型可能导致溢出。 -
性能
进行类型转换可能会影响性能,特别是在处理大规模数据时。最好在数据处理的早期阶段选择合适的类型,以避免不必要的转换。 -
转换不适用的类型
有些类型转换可能不被支持或会引发错误。例如,复数不能直接转换为布尔值。
六、文件I/O
NumPy 提供了多个用于文件 I/O 的函数,可以方便地读写数组数据到文件。
主要方法:
np.save()
和np.load()
:用于保存和读取 NumPy 特有的.npy
格式。np.savetxt()
和np.loadtxt()
:用于保存和读取文本文件。np.savez()
和np.load()
:用于保存和读取包含多个数组的.npz
文件。np.savez_compressed()
:压缩保存多个数组。np.tofile()
和np.fromfile()
:用于原始二进制文件的读写。
例:
(1) np.save()、np.load
np.save()
函数将数组保存到 .npy
格式的文件中,这是一种 NumPy 特有的二进制格式,保存了数组的数据、形状和数据类型。
import numpy as np
# 创建一个数组
arr = np.array([[1, 2, 3], [4, 5, 6]])
# 将数组保存到文件
np.save('array.npy', arr)
# 从文件中加载数组
loaded_arr = np.load('array.npy')
print(loaded_arr)
(2)np.savetxt()、np.loadtxt
np.savetxt()
函数将数组保存为文本文件(例如 .txt
),适用于简单的数据交换或可读性需求。它可以保存为指定的分隔符格式(如逗号、制表符等)。
import numpy as np
# 创建一个数组
arr = np.array([[1.1, 2.2, 3.3], [4.4, 5.5, 6.6]])
# 将数组保存为文本文件
np.savetxt('array.txt', arr, delimiter=',', fmt='%.2f', header='Col1,Col2,Col3')
# 从文本文件中加载数组
loaded_arr = np.loadtxt('array.txt', delimiter=',')
print(loaded_arr)
参数说明:
delimiter
: 分隔符,默认为空格。可以指定为','
,'\t'
等。fmt
: 格式字符串,指定数据的格式,如'%.2f'
表示浮点数保留两位小数。header
: 可选的文件头信息。
(3)np.savez()、np.load()
np.savez()
函数用于将多个数组保存到一个 .npz
文件中,这是一个压缩文件格式,每个数组都会以指定的关键字保存。
import numpy as np
# 创建几个数组
arr1 = np.array([1, 2, 3])
arr2 = np.array([4, 5, 6])
# 将多个数组保存到一个文件中
np.savez('arrays.npz', array1=arr1, array2=arr2)
使用 np.load()
读取 .npz
文件,返回一个字典对象,可以通过关键字访问不同的数组:
import numpy as np
# 从 .npz 文件中加载数据
data = np.load('arrays.npz')
# 访问各个数组
arr1 = data['array1']
arr2 = data['array2']
print(arr1)
print(arr2)
(4)np.savez_compressed()
np.savez_compressed()
函数与 np.savez()
类似,但它会对数据进行压缩,从而减少文件的大小。
import numpy as np
# 创建几个数组
arr1 = np.array([1, 2, 3])
arr2 = np.array([4, 5, 6])
# 将多个数组压缩后保存到一个文件中
np.savez_compressed('arrays_compressed.npz', array1=arr1, array2=arr2)
读取方法与 np.savez()
相同:
import numpy as np
# 从压缩文件中加载数据
data = np.load('arrays_compressed.npz')
# 访问各个数组
arr1 = data['array1']
arr2 = data['array2']
print(arr1)
print(arr2)
(5)np.fromfile()、np.tofile()
这些函数用于读取和写入原始二进制数据,通常用于大文件或特定格式的数据。
import numpy as np
# 创建一个数组
arr = np.array([1, 2, 3, 4, 5])
# 写入二进制文件
arr.tofile('array.bin')
# 从二进制文件中读取数据
loaded_arr = np.fromfile('array.bin', dtype=np.int32)
print(loaded_arr)