NumPy是一个用于科学计算的开源Python库,其名称来源于“Numerical Python”的缩写。它提供了支持大规模多维数组和矩阵运算的功能,此外还包含了大量的数学函数库,可以高效地进行各种数学操作。
import numpy as np
数组创建、属性和操作
数组的创建
可以通过不同的方式向 np.array()
函数传入参数来构建数组。这些参数可以是 Python 列表、元组、其他数组、生成器表达式等,以及一些特定的构造函数。
arr1 = np.array([1, 2, 3, 4, 5]) # 使用 Python 列表创建数组
print("列表创建的数组:",arr1)
arr2 = np.array((1, 2, 3, 4, 5)) # 使用 Python 元组创建数组
print("元组创建的数组:",arr2)
arr3 = np.array(x**2 for x in range(5)) # 使用生成器表达式创建数组
print("生成器表达式创建的数组:",arr3)
existing_array = np.array([10, 20, 30])
arr4 = np.array(existing_array) # 使用其他数组创建数组
print("使用其他数组创建的数组:",arr4)
NumPy提供了许多创建特殊数组的函数,例如:
zeros = np.zeros((3, 3))
print("全零数组:\n", zeros)
ones = np.ones((2, 4))
print("全一数组:\n", ones)
identity = np.eye(3)
print("单位矩阵(对角线为1的方阵):\n", identity)
arange_seq = np.arange(0, 20, 5)
print("等差序列:", arange_seq) # 输出: [ 0 5 10 15]
linspace_seq = np.linspace(0, 1, 5)
print("等间隔序列:", linspace_seq) # 输出: [0. 0.25 0.5 0.75 1. ]
数组的属性
array = np.array([[1, 2, 3], [4, 5, 6]])# 创建一个示例数组
print("数组的维度数 (ndim):", array.ndim) # 输出: 2
print("数组的形状 (shape):", array.shape) # 输出: (2, 3)
print("数组的元素总数 (size):", array.size) # 输出: 6
print("数组的元素数据类型 (dtype):", array.dtype) # 输出: int64
print("数组中每个元素的字节大小 (itemsize):", array.itemsize) # 输出: 8
print("数组中所有元素所占的总字节数 (nbytes):", array.nbytes) # 输出: 48
print("数组的转置 (T):\n", array.T) # 输出: [[1 4][2 5][3 6]]
数组的索引
基本索引:用于访问单个元素,语法类似于Python列表
a[0] # 访问第一个元素
b[2, 1] # 访问二维数组中的特定元素
切片索引:用于访问子数组,语法为 start:stop:step
。
a[1:4] # 访问从第1到第3个元素
b[:, 1] # 访问二维数组的第二列
布尔索引:使用布尔数组来选择符合条件的元素。
mask = a > 30
a[mask] # 访问大于30的元素
花式索引:使用整数数组来访问特定元素。
indices = [0, 2, 4]
a[indices] # 访问特定索引的元素
b[[0, 2], [1, 2]] # 访问二维数组中特定位置的元素
混合索引:结合多种索引方法进行复杂操作。
c[1:3, [2, 4]] # 切片和花式索引混合使用
元素的修改
基本索引修改:直接通过索引修改单个元素。
a = np.array([1, 2, 3, 4, 5])
a[0] = 10 # 修改第一个元素
print(a) # 输出: [10 2 3 4 5]
切片修改:通过切片一次性修改多个元素。
a[1:4] = [20, 30, 40] # 修改多个元素
print(a) # 输出: [10 20 30 40 5]
布尔索引修改:使用布尔索引修改符合条件的元素。
a[a > 25] = 100 # 修改大于25的元素
print(a) # 输出: [10 20 100 100 5]
花式索引修改:通过花式索引修改特定位置的元素。
indices = [0, 2]
a[indices] = [50, 60] # 修改特定索引的元素
print(a) # 输出: [50 20 60 100 5]
数组的维度操作
数组的变形
reshape:改变数组形状,不改变数据。
b = np.arange(6).reshape(2, 3)
print(b)# 输出:[[0 1 2][3 4 5]]
resize:改变数组形状,可能改变数据(原地修改)。
b.resize((3, 2))
print(b)# 输出:[[0 1][2 3][4 5]]
flatten:将多维数组展平成一维数组。
c = b.flatten()
print(c) # 输出: [0 1 2 3 4 5]
ravel:类似于flatten,但返回的是视图(如果可能)。
d = b.ravel()
print(d) # 输出: [0 1 2 3 4 5]
newaxis:增加一个维度。
e = a[:, np.newaxis]
print(e)
# 输出:[[50][20][60][100][5]]
squeeze:删除单维度条目。
f = e.squeeze()
print(f) # 输出: [50 20 60 100 5]
数组的转换
newaxis:增加一个维度。
e = a[:, np.newaxis]
print(e)
# 输出:[[0][1][2][3][4][5]]
squeeze:删除单维度条目。
f = e.squeeze()
print(f) # 输出: [0 1 2 3 4 5]
transpose:转置数组。
g = np.array([[1, 2, 3], [4, 5, 6]])
h = g.transpose()
print(h) # 输出:[[1 4][2 5][3 6]]
swapaxes:交换数组的两个轴。
python复制代码i = np.swapaxes(g, 0, 1)
print(i) # 输出:[[1 4][2 5][3 6]]
T:快速访问转置。
j = g.T
print(j) #输出:[[1 4][2 5][3 6]]
数组的拼接
水平拼接是将多个数组沿着水平方向(列方向)合并成一个新的数组。使用 np.hstack()
函数可以实现水平拼接。
arr1 = np.array([[1, 2, 3],
[4, 5, 6]])
arr2 = np.array([[7, 8, 9],
[10, 11, 12]])
result = np.hstack((arr1, arr2)) # 水平拼接数组
#[[ 1 2 3 7 8 9]
# [ 4 5 6 10 11 12]]
垂直拼接是将多个数组沿着垂直方向(行方向)合并成一个新的数组。使用 np.vstack()
函数可以实现垂直拼接。
arr1 = np.array([[1, 2, 3],
[4, 5, 6]])
arr2 = np.array([[7, 8, 9],
[10, 11, 12]])
result = np.vstack((arr1, arr2)) # 垂直拼接数组
#[[ 1 2 3]
# [ 4 5 6]
# [ 7 8 9]
# [10 11 12]]
数组的拆分
使用 np.hsplit()
函数可以沿着水平方向(列方向)拆分数组。
arr = np.array([[1, 2, 3, 4],
[5, 6, 7, 8]])
result = np.hsplit(arr, 2) # 水平拆分数组
#[array([[1, 2],
# [5, 6]]),
# array([[3, 4],
# [7, 8]])]
使用 np.vsplit()
函数可以沿着垂直方向(行方向)拆分数组。
arr = np.array([[1, 2, 3],
[4, 5, 6],
[7, 8, 9]])
# 垂直拆分数组
result = np.vsplit(arr, 3)
#[array([[1, 2, 3]]),
# array([[4, 5, 6]]),
# array([[7, 8, 9]])]
数组的数据类型
指定数据类型
在创建数组时,可以通过指定 dtype
参数来指定数组的数据类型。常见的数据类型包括整数、浮点数和复数等。例如:
arr_int = np.array([1, 2, 3, 4], dtype=np.int32)
print("整数类型数组:")
print(arr_int)
# 创建浮点数类型的数组
arr_float = np.array([1.0, 2.5, 3.7], dtype=np.float64)
print("浮点数类型数组:")
print(arr_float)
查看和改变数据类型
使用数组的 dtype
属性可以查看数组的数据类型,通过 astype()
方法可以改变数组的数据类型。例如:
python复制代码import numpy as np
arr = np.array([1, 2, 3])
# 查看数组的数据类型
print("数组的数据类型:", arr.dtype)
# 改变数组的数据类型为浮点数
arr_float = arr.astype(np.float64)
print("改变后的数据类型:", arr_float.dtype)
常见数据类型
以下是 NumPy 中常见的数据类型及其对应的类型字符:
数据类型 | 类型字符 | 描述 |
---|---|---|
bool | ? | 布尔型数据类型,存储 True 或 False。 |
int8 | i1 | 8 位整数类型(-128 到 127)。 |
int16 | i2 | 16 位整数类型(-32768 到 32767)。 |
int32 | i4 | 32 位整数类型(-2^31 到 2^31-1)。 |
int64 | i8 | 64 位整数类型(-2^63 到 2^63-1)。 |
uint8 | u1 | 无符号 8 位整数类型(0 到 255)。 |
uint16 | u2 | 无符号 16 位整数类型(0 到 65535)。 |
uint32 | u4 | 无符号 32 位整数类型(0 到 2^32-1)。 |
uint64 | u8 | 无符号 64 位整数类型(0 到 2^64-1)。 |
float16 | f2 | 半精度浮点数类型。 |
float32 | f4 | 单精度浮点数类型。 |
float64 or float | f8 | 双精度浮点数类型。 |
float128 | f16 | 扩展精度浮点数类型。 |
complex64 | c8 | 复数,使用两个 32 位浮点数表示实部和虚部。 |
complex128 or complex | c16 | 复数,使用两个 64 位浮点数表示实部和虚部。 |
complex256 | c32 | 复数,使用两个 128 位浮点数表示实部和虚部。 |
object | O | Python 对象类型,可以包含任意 Python 对象。 |
string_ | S | 固定长度的 ASCII 字符串类型。例如 S10 表示长度为 10 的字符串。 |
unicode_ | U | 固定长度的 Unicode 类型。例如 U10 表示长度为 10 的 Unicode 字符串。 |
数组的运算、通用函数
简单运算
加法、减法、乘法和除法
# 创建两个示例数组
a = np.array([1, 2, 3, 4])
b = np.array([5, 6, 7, 8])
c = a + b # 加法
print("加法结果:", c) # 输出: [ 6 8 10 12]
d = a - b # 减法
print("减法结果:", d) # 输出: [-4 -4 -4 -4]
e = a * b # 乘法
print("乘法结果:", e) # 输出: [ 5 12 21 32]
f = b / a # 除法
print("除法结果:", f) # 输出: [5. 3. 2.33333333 2.]
指数和对数运算
# 创建一个示例数组
g = np.array([1, 2, 3, 4])
h = np.exp(g) # 指数运算
print("指数运算结果:", h) # 输出: [ 2.71828183 7.3890561 20.08553692 54.59815003]
i = np.log(g) # 对数运算
print("对数运算结果:", i) # 输出: [0. 0.69314718 1.09861229 1.38629436]
三角函数运算
# 创建一个示例数组
j = np.array([0, np.pi/2, np.pi])
k = np.sin(j) # 正弦函数
print("正弦函数结果:", k) # 输出: [0.0000000e+00 1.0000000e+00 1.2246468e-16]
l = np.cos(j) # 余弦函数
print("余弦函数结果:", l) # 输出: [ 1.000000e+00 6.123234e-17 -1.000000e+00]
m = np.tan(j) # 正切函数
print("正切函数结果:", m) # 输出: [ 0.00000000e+00 1.63312394e+16 -1.22464680e-16]
比较运算
比较运算符
# 创建两个示例数组
a = np.array([1, 2, 3, 4])
b = np.array([5, 2, 7, 1])
c = a == b # 等于
print("等于运算结果:", c) # 输出: [False True False False]
d = a != b # 不等于
print("不等于运算结果:", d) # 输出: [ True False True True]
e = a > b # 大于
print("大于运算结果:", e) # 输出: [False False False True]
f = a <= b # 小于等于
print("小于等于运算结果:", f) # 输出: [ True True True False]
逻辑运算
g = np.logical_and(a > 2, b < 5) # 逻辑与
print("逻辑与运算结果:", g) # 输出: [False False True False]
h = np.logical_or(a < 2, b > 5) # 逻辑或
print("逻辑或运算结果:", h) # 输出: [ True False True True]
i = np.logical_not(a == b) # 逻辑非
print("逻辑非运算结果:", i) # 输出: [ True False True True]
通用函数
基本数学运算
# 创建示例数组
a = np.array([1, 2, 3, 4])
b = np.add(a, 2) # 加法
print("加法:", b) # 输出: [3 4 5 6]
c = np.multiply(a, 3) # 乘法
print("乘法:", c) # 输出: [ 3 6 9 12]
d = np.exp(a) # 指数函数
print("指数函数:", d) # 输出: [ 2.71828183 7.3890561 20.08553692 54.59815003]
聚合函数
sum_a = np.sum(a) # 求和
print("数组求和:", sum_a) # 输出: 10
mean_a = np.mean(a) # 求平均值
print("数组平均值:", mean_a) # 输出: 2.5
std_a = np.std(a) # 求标准差
print("数组标准差:", std_a) # 输出: 1.118033988749895
比较运算
x = np.array([1, 2, 3])
y = np.array([2, 2, 2])
result = np.greater(x, y) # 返回布尔数组
print("大于运算:", result) # 输出: [False False True]
这些ufunc函数在处理NumPy数组时非常高效,能够简化代码并且利用NumPy的向量化操作进行快速计算。使用这些函数可以有效地进行数学运算、逻辑运算以及对数组元素的操作,是NumPy强大功能的重要组成部分。
函数名 | 描述 | 示例 |
---|---|---|
np.add | 元素级别的加法 | np.add([1, 2], [3, 4]) 返回 [4, 6] |
np.subtract | 元素级别的减法 | np.subtract([1, 2], [3, 4]) 返回 [-2, -2] |
np.multiply | 元素级别的乘法 | np.multiply([1, 2], [3, 4]) 返回 [3, 8] |
np.divide | 元素级别的除法 | np.divide([1, 2], [3, 4]) 返回 [0.333, 0.5] |
np.power | 元素级别的幂运算 | np.power([1, 2], [3, 4]) 返回 [1, 16] |
np.exp | 元素级别的指数函数 | np.exp([1, 2]) 返回 [2.718, 7.389] |
np.log , np.log10 , np.log2 | 元素级别的对数函数 | np.log([1, np.e]) 返回 [0, 1] |
np.sin , np.cos , np.tan | 元素级别的三角函数 | np.sin([0, np.pi/2]) 返回 [0, 1] |
np.arcsin , np.arccos , np.arctan | 元素级别的反三角函数 | np.arcsin([0, 1]) 返回 [0, 1.570] |
np.sqrt | 元素级别的平方根 | np.sqrt([1, 4]) 返回 [1, 2] |
np.abs | 元素级别的绝对值 | np.abs([-1, -2]) 返回 [1, 2] |
np.ceil , np.floor | 元素级别的向上取整和向下取整 | np.ceil([1.1, 2.9]) 返回 [2, 3] |
np.rint | 元素级别的四舍五入 | np.rint([1.1, 2.5]) 返回 [1, 3] |
np.sign | 元素级别的符号函数 | np.sign([-1, 2]) 返回 [-1, 1] |
np.maximum , np.minimum | 元素级别的最大值和最小值 | np.maximum([1, 2], [2, 1]) 返回 [2, 2] |
np.logical_not | 元素级别的逻辑非 | np.logical_not([True, False]) 返回 [False, True] |
np.logical_and , np.logical_or , np.logical_xor | 元素级别的逻辑运算 | np.logical_and([True, False], [True, True]) 返回 [True, False] |
np.bitwise_and , np.bitwise_or , np.bitwise_xor | 元素级别的位运算 | np.bitwise_and([1, 0], [1, 1]) 返回 [1, 0] |
np.isnan , np.isinf | 元素级别的判断是否为NaN或无穷大 | np.isnan([np.nan, 1]) 返回 [True, False] |
np.isfinite | 元素级别的判断是否为有限数 | np.isfinite([np.inf, 1]) 返回 [False, True] |
广播运算
广播的规则
NumPy的广播规则定义了在进行元素级别操作时,如何处理不同形状的数组。当进行运算时,NumPy会比较两个数组的形状,然后尝试在较小的数组上“广播”操作,使得它们的形状能够对齐。
广播规则如下:
- 维度不足的数组在其缺失的维度上进行扩展:
- 将其形状用1填充,直到两个数组的形状能够对齐。
- 对于每对对应维度,数组形状要么相等,要么其中一个为1:
- 如果两个数组的形状在某个维度上相等,或者其中一个数组在该维度上的长度为1,则认为它们是兼容的。
- 广播之后,每个数组的维度等于两个输入数组中的最大维数。
广播的示例
广播的基本操作
在这个例子中,标量 b
被扩展成了形状为 (3,)
的数组 [2, 2, 2]
,然后与数组 a
进行元素级别的加法运算。
a = np.array([1, 2, 3]) # 形状为 (3,)
b = 2 # 标量,形状为 ()
# 对数组 a 和标量 b 进行加法运算,b 被广播为 [2, 2, 2]
c = a + b
print(c) # 输出: [3 4 5]
更复杂的广播示例
在这个例子中,数组 B
被扩展成了形状为 (2, 3)
的数组 [[10, 20, 30], [10, 20, 30]]
,然后与数组 A
进行元素级别的加法运算。
A = np.array([[1, 2, 3], [4, 5, 6]]) # 形状为 (2, 3)
B = np.array([10, 20, 30]) # 形状为 (3,)
# 对数组 A 和 B 进行加法运算,B 被广播为 [[10, 20, 30], [10, 20, 30]]
C = A + B
print(C) # 输出:[[11 22 33][14 25 36]]
随机模块
下表总结了NumPy中的numpy.random
模块的主要功能、常用参数以及返回值:
函数 | 功能与描述 | 常用参数 | 返回值 |
---|---|---|---|
numpy.random.rand | 生成指定形状的随机数数组,范围在[0, 1)之间。 | 形状 (size ) | 随机数组 |
numpy.random.randn | 生成指定形状的标准正态分布随机数数组。 | 形状 (size ) | 随机数组 |
numpy.random.randint | 生成指定范围内的整数随机数数组。 | 最小值 (low ), 最大值 (high , 不包括在内), 形状 (size ) | 随机整数数组 |
numpy.random.random_sample | 生成指定形状的随机数数组,范围在[0, 1)之间。 | 形状 (size ) | 随机数组 |
numpy.random.random | 生成指定形状的随机数数组,范围在[0, 1)之间。 | 形状 (size ) | 随机数组 |
numpy.random.choice | 从给定的一维数组中随机抽取元素。 | 数组 (a ), 抽样个数 (size , 可选), 替换与否 (replace , 可选), 概率 (p , 可选) | 抽样结果数组 |
numpy.random.shuffle | 随机打乱给定的数组。 | 数组 (x ) | 无,原地打乱数组 |
numpy.random.permutation | 返回随机排列给定数组的副本。 | 数组 (x ) | 打乱后的数组副本 |
numpy.random.seed | 设定随机数生成器的种子,以便复现随机数序列。 | 种子值 (seed ) | 无,设定随机数种子 |
numpy.random.normal | 生成指定形状的正态分布随机数数组。 | 均值 (loc ), 标准差 (scale ), 形状 (size ) | 随机数组 |
numpy.random.uniform | 生成指定形状的均匀分布随机数数组。 | 最小值 (low ), 最大值 (high ), 形状 (size ) | 随机数组 |
numpy.random.exponential | 生成指定形状的指数分布随机数数组。 | 每单位时间的事件率 (scale ), 形状 (size ) | 随机数组 |
numpy.random.poisson | 生成指定形状的泊松分布随机数数组。 | 预期的事件发生率 (lam ), 形状 (size ) | 随机数组 |
numpy.random.gamma | 生成指定形状的伽马分布随机数数组。 | 形状参数 (shape ), 尺度参数 (scale , 可选), 形状 (size ) | 随机数组 |
numpy.random.beta | 生成指定形状的贝塔分布随机数数组。 | 形状参数 (a ), 形状参数 (b ), 形状 (size ) | 随机数组 |
numpy.random.chisquare | 生成指定形状的卡方分布随机数数组。 | 自由度 (df ), 形状 (size ) | 随机数组 |
numpy.random.binomial | 生成指定形状的二项分布随机数数组。 | 试验次数 (n ), 成功概率 (p ), 形状 (size ) | 随机数组 |
numpy.random.multivariate_normal | 生成指定形状的多变量正态分布随机数数组。 | 均值向量 (mean ), 协方差矩阵 (cov ), 形状 (size ) | 多维随机数组 |
numpy.random.standard_normal | 生成指定形状的标准正态分布随机数数组。 | 形状 (size ) | 随机数组 |
numpy.random.standard_t | 生成指定形状的学生 t 分布随机数数组。 | 自由度 (df ), 形状 (size ) | 随机数组 |
文件存取操作
文本文件存取操作
从文本文件读取数据 (np.loadtxt
)
# 从文本文件读取数据
data = np.loadtxt('data.txt', delimiter=',') # 可以指定分隔符,默认是空白符
print("从文本文件读取的数据:")
print(data)
- 参数解释:
'data.txt'
是要读取的文件名。delimiter=','
指定了数据之间的分隔符,这里假设是逗号分隔。
将数据保存到文本文件 (np.savetxt
)
data = np.array([[1, 2, 3],
[4, 5, 6]])
# 将数据保存到文本文件
np.savetxt('saved_data.txt', data, delimiter=',')
- 参数解释:
'saved_data.txt'
是要保存的文件名。data
是要保存的NumPy数组。delimiter=','
指定了数据之间的分隔符。
二进制文件存取操作
从二进制文件读取数据 (np.load
)
# 从二进制文件读取数据
data = np.load('data.npy')
print("从二进制文件读取的数据:")
print(data)
- 参数解释:
'data.npy'
是要读取的二进制文件名,.npy
是NumPy默认的二进制文件格式。
将数据保存到二进制文件 (np.save
)
data = np.array([[1, 2, 3],
[4, 5, 6]])
# 将数据保存到二进制文件
np.save('saved_data.npy', data)
- 参数解释:
'saved_data.npy'
是要保存的二进制文件名,.npy
是NumPy默认的二进制文件格式。data
是要保存的NumPy数组。