python第三方库numpy学习笔记
numpy介绍
numpy是一款功能强大的Python库,专注于科学计算和数据处理。它底层使用C语言实现,按照类型存储数据,因此比Python列表更高效。numpy提供了简洁易读的语法和强大的函数库,用于操作数组、矩阵乘法、傅里叶变换等等。此外,numpy也提供了大量的线性代数和随机数生成函数,方便进行向量和矩阵运算,同时也可以生成服从不同分布的随机数。总之,numpy在科学计算和数据处理中是一个非常重要的工具,为用户提供了高效的数据存储方式和快捷的数据处理方法。
numpy下载和导入
- 下载
如果使用的是conda
则无需下载,conda
中内置了numpy
库。否则使用pip命令下载。
pip install numpy
- 导入
import numpy as np
numpy使用
首先在这里声明一个range可迭代对象,以便后面使用
array_data = range(6)
numpy创建数组
# 方式一: np.array()方法
# 参数:
# p_object: 数据类型可为ndarray,Iterable,int,float
# dtype: 用于指定返回的ndarray对象的数据类型
# 返回值: ndarray数组对象
array = np.array(array_data) # 可通过type(array)查看返回值类型
# 方式二: np.arange()方法
# 类似于range方法,同样返回`ndarray`数组对象。
array = np.arange(0, 6, 2) # 创建从0到5步长为2的数组
# 方式三: np.zeros()方法
# 创建全是0的数组,同样返回ndarray数组对象。
array = np.zeros(6) # 创建6个0的数组
# 方式四: np.ones()方法
# 创建全是1的数组,同样返回ndarray数组对象。
array = np.ones(6) # 创建6个1的数组
# 方式五: np.zeros_like()方法
# 创建全是0的数组,与传入的数据无关,与传入的数据维度有关,同样返回ndarray对象
array = np.zeros_like(array_data) # 创建6个0的数组
# 方式六: np.ones_like()方法
# 创建全是1的数组,与传入的数据无关,与传入的数据维度有关,同样返回ndarray对象
array = np.ones_like(array_data) # 创建6个1的数组
ndarray数组对象属性
# 数组元素类型
print(array.dtype)
# 数组维度
print(array.shape)
# 数组维数
print(array.ndim)
# 数组元素个数
print(array.size)
# 数组单个元素所占空间大小 字节数
print(array.itemsize)
# 数组总字节数
print(array.nbytes)
# 数组对象的转置视图 shape改变 如shape=(3,2)转为如shape=(2,3)
print(array.T)
# 扁平迭代器
print(array.flat)
ndarray数组对象计算
与python列表不同,数组可以直接计算,是对数组中每一个种子进行计算
array = np.array(array_data) # array返回值 [0 1 2 3 4 5]
array_1 = array * 2 # array_1返回值 [ 0 2 4 6 8 10]
ndarray
数组对象之间计算,在最后一位开始比较,比较位如果相同或有一项为1则比较通过,开始比较下一项。如果比较不通过,则无法进行计算
# 2, 1, 3
# 2, 3
# 最后一位都是3,相同,开始比较下一位
# 下一位1,2包含1比较通过,可以进行计算
array_1 = np.array(array_data).reshape((2, 1, 3))
array_2 = np.array(array_data).reshape((2, 3))
array_3 = array_1 * array_2
ndarray数组对象dtype属性
dtype属性用于指定数组的数据类型,可在创建的时候设置数组对象的dtype
属性,也可以修改数组对象的dtype
属性。
# 创建数组对象时设置dtype属性 i4指int32是简写方式,int32表示的是一个32位(4字节)的整数类型,一个字节是8位
array = np.array(array_data, dtype="i4")
# 修改原数组的dtype属性
array.dtype = "i8"
# 修改数组dtype属性,原数组dtype属性不变,返回一个修改dtype属性后的新的数组
array_1 = array.astype("i8")
下面是以表格的形式列出ndarray数组对象dtype属性(内容由chatgpt
生成,仅供参考)
数据类型 | 代码写法 | 字符串写法 | 简写 | 解释说明 |
---|---|---|---|---|
int8 | np.int8 | “int8” | “i1” | 有符号8位整数 |
uint8 | np.uint8 | “uint8” | “u1” | 无符号8位整数 |
int16 | np.int16 | “int16” | “i2” | 有符号16位整数 |
uint16 | np.uint16 | “uint16” | “u2” | 无符号16位整数 |
int32 | np.int32 | “int32” | “i4” | 有符号32位整数 |
uint32 | np.uint32 | “uint32” | “u4” | 无符号32位整数 |
int64 | np.int64 | “int64” | “i8” | 有符号64位整数 |
uint64 | np.uint64 | “uint64” | “u8” | 无符号64位整数 |
float16 | np.float16 | “float16” | “f2” | 半精度浮点数 |
float32 | np.float32 | “float32” | “f4” | 单精度浮点数 |
float64 | np.float64 | “float64” | “f8” | 双精度浮点数 |
complex64 | np.complex64 | “complex64” | “c8” | 由两个32位浮点数组成的复数 |
complex128 | np.complex128 | “complex128” | “c16” | 由两个64位浮点数组成的复数 |
bool_ | np.bool_ | “bool_” | “?” | 布尔型数据类型(True 或者 False) |
object_ | np.object_ | “object_” | None | Python对象类型,可以存储任意Python对象 |
string_ | np.string_ | “string_” | “S” | 字符串类型 |
unicode_ | np.unicode_ | “unicode_” | “U” | 类型 |
float_ | np.float_ | “float_” | None | 浮点数类型(与float64相同) |
int_ | np.int_ | “int_” | None | 默认的整数类型(类似于 C 语言中的 long,int32 或 int64) |
uint | np.uint | “uint” | None | 无符号整数类型(与uint64相同) |
datetime64 | np.datetime64 | “datetime64” | “M8” | 固定单位的时间日期类型(精度可配置) |
timedelta64 | np.timedelta64 | “timedelta64” | “m8” | 固定单位的时间差类型(精度可配置) |
numpy自定义数据类型dtype写法
# 先定义一条数据
array_data = [
("王小明", 18, [98, 90, 96]),
("海贝", 17, [89, 96, 92])
]
# dtype写法一 U3表示最大3个Unicode字符,超过的部分会被截取。3i4表示3个int32整数
array = np.array(array_data, dtype="U3, i4, 3i4")
# dtype写法二 列表中嵌套字典 可为column取别名
array = np.array(array_data, dtype=[("name", "str_", 3), ("age", "int32"), ("score", "int32", 3)])
# dtype写法三 与写法二类似
array = np.array(array_data, dtype=[("name", np.str_, 3), ("age", np.int32), ("score", np.int32, 3)])
# dtype写法四 与写法二类似
array = np.array(array_data, dtype=[("name", "U3"), ("age", "i4"), ("score", "3i4")])
# dtype写法五 字典形式
array = np.array(data,dtype={"names": ["name", "age", "score"],"formats": ["U2", "i4", "3i4"]})
# 还有其它写法
ndarray数组修改维度
numpy可创建多维数组,最常用的是二维数组
array = np.array(array_data)
# 视图变维(数据共享)
# 方式一
array_1 = array.reshape((2, 3)) # 变为二维数组 2行3列,共6个元素
# 方式二
array_2 = array_1.ravel() # 拉平 变为一维数组
# 复制变维(数据独立)
# 方式一
array_3 = array.copy() # 复制 维度不变
# 方式二
array_4 = array_1.flatten() # 拉平 变为一维数组
# 修改原数组维度
# 方式一
array.resize((2, 3)) # 变为二维数组 2行3列,共6个元素
# 方式二
array.shape = (6,) # 变为一维数组
ndarray数组取值
- 一维数组取值
array = np.array(array_data)
# 取单个值
print(array[0])
# 取多个值
print(array[[0,1]])
- 多维数组取值
# 自定义数据类型
array_data = [
("王小明", 18, [98, 90, 96]),
("海贝", 17, [89, 96, 92])
]
array = np.array(array_data, dtype=[("name", "str_", 3), ("age", "int32"), ("score", "int32", 3)])
# 方法一 下标取值
print(array[0][0])
# 方法二 下标取值
print(array[[0,1]])
# 方式三 下标+别名取值
print(array[0]["name"])
# 方式四 下标+别名取值
print(array[[0,1]][["name", "age"]])
# 方式五 别名取值
print(array["name"])
# 方式六 别名取值
print(array[["name", "age"]])
# 非自定义数据类型
array = np.array(array_data).reshape(2, 3)
# 方式一 下标取值
print(array[0][0])
# 方式二 下标取值
print(array[1,0]) # 取第2行第1列的数据
# 方式三 下标取值
print(array[...,0]) # 取第1列的数据
# 方式四 去多列
print(array[...,[0,2]]) # 取第1列和第3列的数据
# 方式五 取多行
print(array[[0,1]]) # 取第1行和第2行的数据
# 方式六 取多个值
print(array[[0,1],[0,1]]) # 取第1行第1列和第2行第2列的数据,返回的是一个一维数组
ndarray数组切片
- 一维数组切片
与python列表切片一样
array = np.array(array_data)
print(array[1:5:2]) # 从1切到5,不包括5,步长为2
- 多维数组切片
二维数组切片 逗号分隔 前面切行 后边切列
array = np.array(array_data)
# 方式一
print(array[1:, :2])
# 方式二: 直切行
print(array[1:])
# 方式三: 只切列
print(array[..., :2])
注: 切片取值可参考ndarray数组取值部分的取多行和取多列
ndarray数组掩码
-
基于布尔值的掩码 用于过滤
# 掩码 只返回掩码为True的种子 返回的是一维数组 array = np.array(array_data) mask = [True, False, True, True, False, True] print(array[mask]) # 例子 按条件过滤 mask = array % 2 == 0 print(array[mask]) # 逻辑运算 &表示且,|表示或,~表示非 # 且 mask = (array % 2 == 0) & (array != 2) print(array[mask]) # 或 mask = (array % 2 == 0) | (array == 1) print(array[mask]) # 非 mask = ~(array % 2 == 0) print(array[mask])
-
基于索引的掩码 排序
array = np.array(array_data) rank = [5, 0, 1, 4, 3, 2] # 原来索引是5的为数组第一个种子,原来索引为0的为数组第二个种子 print(array[rank])
ndarray数组组合拆分
- 多维数组组合拆分
# v是垂直方向(行) h是水平方向(列) d是深度方向
array_1 = np.arange(1, 7).reshape(2, 3)
array_2 = np.arange(7, 13).reshape(2, 3)
# 垂直方向组合
array_3 = np.vstack((a, b))
# 垂直方向拆分 拆分成两个数组
array_4, array_5 = np.vsplit(array_3, 2)
# 水平方向上组合
array_6 = np.hstack((array_1, array_2))
# 水平方向上拆分 拆分成两个数组
array_7, array_8 = np.hsplit(array_6, 2)
# 深度方向上组合
array_9 = np.dstack((array_1, array_2))
# 深度方向上拆分 拆分成两个数组
array_10, array_11 = np.dsplit(array_9, 2)
# 在任意方向上组合拆分 参数axis 0 垂直(行) 1 水平(列) 2 深度 记法: 0像v,1像h。也可以这样记,大写的一是横着的,也就是水平的
# 垂直方向上组合
array_12 = np.concatenate((array_1, array_2), axis=0)
# 垂直方向上拆分 拆分成两个数组
array_13, array_14 = np.split(array_12, 2, axis=0)
- 长度不相等数组组合(填充使其相等)
array_1 = np.array([1, 2, 3, 4, 5])
array_2 = np.array([1, 2, 3, 4])
# 填充b使其长度与a相同
# 参数解释
# pad_width 要填充的位置 先行(v)后列(h) (0, 1)指在行方向开头填充0个,在末尾填充1个,由于没有列,如果有列的话,在列方向开头填充0
# 列,在末尾填充1列。如多维数组pad_width=((1,2),(3, 4))指在行方向开头填充1行,在末尾填充2行。在列方向开头填充3列,在列方向末尾
# 填充4列。
# mode 填充模式 "constant"指使用常数填充 可用constant_values设置
# constant_values 要填充的常数 与pad_width对应 默认为0 这里constant_values=-1指全部填充-1 如constant_values=(1,-1)指
# 行方向开头填充1,在末尾填充-1
array_2 = np.pad(array_2, pad_width=(0, 1), mode="constant", constant_values=-1)
array_3 = np.vstack((array_1, array_2))
- 一维数组组合
array_1 = np.arange(1, 7)
array_2 = np.arange(7, 13)
# 在垂直方向上
array_3 = np.row_stack((array_1, array_2))
# 在水平方向上
array_4 = np.column_stack((array_1, array_2))
numpy时间相关
创建数组时需要指定特定的dtype
# M8时间日期类型,s指精确到秒
array_data = ['2023-10-27 09:36:00', '2024-08-13', '2023', '2023-10-28 09:00:00']
array = np.array(array_data, dtype="M8[s]")
# 数组时间相减得到时间差 时间差单位与设置的dtype的精度有关
print(array[-1] - array[0]) # 返回 84240 seconds
# 数组时间减去数字得到减后的时间数组 数字同样与设置的dtype的精度有关
print(array - 60)
numpy创建等差等比数列数列
-
等差数列(差值相同)
# 参数 # start 必填项,起始值 # stop 必填项,终止值,如果endpoint为True,该值包含在数列中 # num 生成的等步长的样本数量,默认为50 # endpoint 该值为True,数列中包含stop值,反之不包含,默认为True # retstep 如果为True时,生成的数组中显示间距,反之不显示。默认为False # dtype ndarray的数据类型 # axis 方向 array = np.linspace(1, 6, 6) # 起始值1,终止值6,数量6,返回[1. 2. 3. 4. 5. 6.] # 设置 endpoint=False array = np.linspace(1, 7, 6, endpoint=False) # 返回[1. 2. 3. 4. 5. 6.] # 设置 retstep=True step, array = np.linspace(1, 6, 6, retstep=True) # 1.0 [1. 2. 3. 4. 5. 6.]
-
等比数列
# 参数 # start 必填项,起始值 # stop 必填项,终止值,如果endpoint为True,该值包含在数列中 # num 生成的等步长的样本数量,默认为50 # endpoint 该值为True,数列中包含stop值,反之不包含,默认为True # base 对数log的底数 # dtype ndarray的数据类型 # axis 方向 array = np.logspace(1, 6, 6, base=2) # 等同于2 ** array,返回值[ 2. 4. 8. 16. 32. 64.]
numpy统计函数
array = np.array(array_data).reshape(2, 3)
# 求平均值 默认求出数组所有元素的平均值
print(array.mean())
print(np.mean(array))
# 某个方向上的平均值 垂直方向 列的平均值
print(array.mean(axis=0))
print(np.mean(array, axis=0))
# 某个方向上的平均值 垂直方向 行的平均值
print(array.mean(axis=1))
print(np.mean(array, axis=1))
# 求中位数 默认求出数组所有元素的中位数 如果数量是偶数的话区最中间两个数的平均值
print(np.median(array))
# 某个方向上的中位数 垂直方向 列的中位数
print(np.median(array, axis=0))
# 某个方向上的中位数 水平方向 行的中位数
print(np.median(array, axis=1))
# 求标准差 标准差是一组数据平均值分散程度的一种度量,在概率统计中最常使用作为测量一组数值的离散程度之用。为方差开算术平方根。
# 一个较大的标准差,代表大部分数值和其平均值之间差异较大
# 一个较小的标准差,代表这些数值较接近平均值
print(array.std())
print(np.std(array))
# 求方差 描述的是一个随机变量的离散程度,即一组数字与其平均值之间的距离的度量 与标准差类似
# 标准差有计量单位 方差无计量单位
print(array.var())
print(np.var(array))
# 求最大值
print(array.max())
print(np.max(array))
# 垂直方向 列的最大值
print(array.max(axis=0))
print(np.max(array, axis=0))
# 求最小值
print(array.min())
print(np.min(array))
# 垂直方向 列的最小值
print(array.min(axis=0))
print(np.min(array, axis=0))
# 求和
print(array.sum())
print(np.sum(array))
# 垂直方向 列求和
print(array.sum(axis=0))
print(np.sum(array, axis=0))
# 求加权平均值
weights = np.array([[0.1, 0.1, 0.2], [0.4, 0.1, 0.1]])
print(np.average(array, weights=weights))
# 在垂直方向上计算加权平均值
weights = np.array([0.4, 0.6])
print(np.average(array, weights=weights, axis=0))
# 在水平方向上计算加权平均值
weights = np.array([0.4, 0.4, 0.2])
print(np.average(array, weights=weights, axis=1))
numpy随机数
# np.random.rand() 生成(0,1)均匀分布的随机数
print(np.random.rand(2, 3)) # 生成2行3列的(0,1)均匀分布的随机数 2,3类似于shape,2维
# np.random.randn() 生成标准正态分布随机数 是以0为均值,以1为标准差的正态分布,记为N(0,1)
print(np.random.randn(6))
# np.random.randint() 生成随机整数 范围区间为[low,high)
# 参数
# low为最小值,high为最大值,size为数组维度大小。
# high没有填写时,默认生成的随机数范围为[0,low)
print(np.random.randint(1, 6, size=(2, 3))) # 生成2行3列最小值为1最大值为6,不包含6的整数数组
# np.random.sample() 生成[0.0,1.0)半开区间内的随机浮点数
print(np.random.sample((2, 3))) # 生成2行3列的[0.0,1.0)半开区间内的随机浮点数
# np.random.seed() 随机种子 使生成的随机数是可预测的
np.random.seed(1) # 开启随机种子1
array_1 = np.random.randint(1, 8, 6)
np.random.seed(1) # 开启随机种子1
array_2 = np.random.randint(1, 8, 6)
# np.random.normal() 正态分布
# 参数
# loc指定均值
# scale指定标准差
# size指定数组的形状
print(np.random.normal(1, 3, 10)) # 均值1,标准差3,10个数
numpy文件操作
# np.loadtxt() 读取txt、csv文件
# 参数
# fname 指定要读取的文件
# dtype 数据类型,默认为float
# comments 注释字符集开始的标志,默认为#
# delimiter 分隔符
# converters 字典。将特定列的数据转换为字典中对应的函数的浮点数据 如将控制转换为0 converters={列索引:处理的函数}
# skiprows 跳过特定行数据
# usecols 元组 用来指定要读取的数据的列
# encoding 编码
# 读取csv文件
array = np.loadtxt("data.csv", delimiter=",", skiprows=1)
ndarray数组对象去重
array_data = [1, 3, 5, 2, 5, 5, 1, 3]
array = np.array(array_data).reshape(4, 2)
# 对整个数组去重 返回一维数组
array_1 = np.unique(array) # [1 2 3 5]
# 在某个方向上去重 在垂直方向上 行 去重
array_2 = np.unique(array, axis=0)
# return_index 如果为True 返回新数组在原数组中的索引
array_3, index = np.unique(array, axis=0, return_index=True)
# return_inverse 如果为True 返回原数组在元新数组中的索引
array_4, inverse = np.unique(array, axis=0, return_inverse=True)
# return_counts 如果为True 返回新数组在原数组中出现的次数
array_3, counts = np.unique(array, axis=0, return_counts=True)
ndarray数组对象排序
# np.sort()
array_data = [1, 3, 5, 2, 5, 5, 1, 3]
array = np.array(array_data).reshape(4, 2)
# 参数
# kind 排序方法 默认quicksort(快速排序)
# order 若设置了该字段表示要排序的字段
# 默认对最内层进行排序 列
print(np.sort(array))
# 在垂直方向上排序
print(np.sort(array, axis=0))
# 在水平方向上排序
print(np.sort(array, axis=1))
# 自定义数据类型
array_data = [
("王小明", 17, [98, 90, 96]),
("海贝", 17, [89, 96, 92]),
("小红", 19, [89, 97, 82]),
]
array = np.array(array_data, dtype=[("name", "str_", 3), ("age", "int32"), ("score", "int32", 3)])
# 根据第一门成绩排序,如果第一门成绩相同,根据第二门成绩排序 升序排序
print(np.sort(array, order="score"))
# 先根据年龄排序,如果年龄相同 根据成绩排序
print(np.sort(array, order=("age", "score")))
ndarray数组对象反转
# np.flip() 默认水平和垂直方向全反转
array_data = [1, 3, 5, 2, 5, 5, 1, 3]
array = np.array(array_data).reshape(4, 2)
print(np.flip(array))
# 在垂直方向反转 行
print(np.flip(array, axis=0))
# 在水平方向上反转 列
print(np.flip(array, axis=1))
# 自定义数据类型
array_data = [
("王小明", 17, [98, 90, 96]),
("海贝", 17, [89, 96, 92]),
("小红", 19, [89, 97, 82]),
]
array = np.array(array_data, dtype=[("name", "str_", 3), ("age", "int32"), ("score", "int32", 3)])
# 在垂直方向上反转 行
print(np.flip(array))
ndarray数组对象空值
# np.nan 空值
array_data = [1, np.nan, 5, 2, np.nan, 5, 1, 3]
array = np.array(array_data).reshape(4, 2)
# 去除空值
array_1 = array[~np.isnan(array)]
# 替换空值
array[np.isnan(array)] = 0
numpy增删操作
# np.append()
array = np.array(array_data).reshape(2, 3)
# 添加一行
array_1 = np.append(array, values=[[6, 7, 8]], axis=0)
# 添加一列 列数要与array列数一样
array_2 = np.append(array, values=[[6], [7]], axis=1)
# 等同于下面的写法
array_3 = np.append(array, values=np.array([6, 7]).reshape(2, 1), axis=1)
# np.insert()
array_4 = np.insert(array, 1, values=[6, 7, 8], axis=0) # 在索引为1的行位置插入一行[6, 7, 8]
array_5 = np.insert(array, 1, values=6, axis=0) # 在索引为1的行位置插入一行[6, 6, 6]
array_6 = np.insert(array, 1, values=[6, 7], axis=1) # 在索引为1的列位置插入一列[6, 7]
array_7 = np.insert(array, 1, values=6, axis=1) # 在索引为1的列位置插入一列[6, 6]
# np.delete()
array = np.array(array_data).reshape(3, 2)
# 删除一行
array_1 = np.delete(array, 1, axis=0)
# 删除多行
array_2 = np.delete(array, [1, 2], axis=0)
# 删除一列
array_3 = np.delete(array, 1, axis=1)
# 删除多列
array_4 = np.delete(array, [0, 1], axis=1)
ndarray数组对象where查询
# np.where()
# 参数
# condition 查询条件 x 查询条件为真时返回值, y 查询条件为假时返回值
# 若不填写x y则返回为真时的索引,是两个数组,分别对应行坐标和列坐标
array = np.array(array_data).reshape(3, 2)
print(np.where(array > 3, array, 0))
print(np.where(array > 3)) # 返回(array([2, 2], dtype=int64), array([0, 1], dtype=int64)) 索引为2,0和2,1
# np.argwhere 直接返回查询条件为真的索引
print(np.argwhere(array > 3)) # 返回[[2 0] [2 1]] 索引为2,0和2,1
使用的numoy版本为 1.24.4
文章编写与2023年12月