Python科学计算模块NumPy学习笔记

350次阅读
没有评论

共计 6019 个字符,预计需要花费 16 分钟才能阅读完成。

基本介绍

NumPy:Numerical Python 的缩写,提供了底层基于 C 语言实现的数值计算库,与 Python 内置的 list 数据结构相比,其支持更加规范的数据类型和极其丰富的操作接口,速度也更快。

安装 NumPy

NumPy 是第三方库,所以在使用前必须先安装 NumPy。可以使用 pip 命令安装:pip install numpy

安装完就可以写 NumPy 代码了。一般流程是先import numpy,为了后续调用方便,通常在 import 完之后,还给它一个缩写形式as np

创建 NumPy 数组 ndarray

NumPy 默认 ndarray 所有元素的类型是相同的。如果传进来的列表中包含不同的类型,则统一为同一类型,优先级:str > float > int。

使用 np.array()

import numpy as np

n = np.array([1, 2, 3])
print(n.shape)  # 形状:(3,)

使用 np.ones()

创建一个所有元素都为 1 的多维数组。

n = np.ones((3, 2), dtype=np.int8)  # 默认是 float 类型
print(n.shape)  # 形状:(3, 2)

创建一个所有元素都为 0 的多维数组,使用 np.zeros()。

创建一个所有元素都为指定元素的多维数组,使用 np.full():

n = np.full((3, 2), fill_value=6)
print(n)
# 输出:# [[6 6]
#  [6 6]
#  [6 6]]

使用 np.eye()

创建一个单位矩阵:主对角线都是 1,其他都是 0 的二维数组。

n = np.eye(5, 5, dtype=np.int8)
print(n)
# 输出:# [[1 0 0 0 0]
#  [0 1 0 0 0]
#  [0 0 1 0 0]
#  [0 0 0 1 0]
#  [0 0 0 0 1]]

# k= 1 向右偏移 1 个位置,k=- 1 向左偏移 1 个位置
n = np.eye(5, 5, k=1, dtype=np.int8)
print(n)
# [[0 1 0 0 0]
#  [0 0 1 0 0]
#  [0 0 0 1 0]
#  [0 0 0 0 1]
#  [0 0 0 0 0]]

使用 np.linspace()

创建一个等差数列。参数说明:

  • start: 开始值
  • stop: 结束值
  • num=50: 等差数列中默认有 50 个数
  • endpoint=True: 是否包含结束值
  • retstep=False: 是否返回等差值(步长)
  • dtype=None: 元素类型
n = np.linspace(0, 10, num=6, dtype=np.int8)
print(n)  # [0  2  4  6  8 10]

使用 np.arange()

创建一个数值范围的数组,和 Python 中的 range 功能类似。

n = np.arange(10)
print(n)  # [0 1 2 3 4 5 6 7 8 9]
n = np.arange(2, 10)
print(n)  # [2 3 4 5 6 7 8 9]
n = np.arange(2, 10, 2)
print(n)  # [2 4 6 8]

使用 np.random.randint()

创建一个随机整数的多维数组。

import numpy as np
import matplotlib.pyplot as plt

n = np.random.randint(3)
print(n)  # 随机范围:[0, 3)
n = np.random.randint(3, 10)
print(n)  # 随机范围:[3, 10)
n = np.random.randint(3, 10, size=5)
print(n)  # 一维
n = np.random.randint(3, 10, size=(2, 3))
print(n)  # 二维

n = np.random.randint(0, 256, size=(20, 40, 3))
plt.imshow(n)  # 图像处理
plt.show()  # 图像显示

使用 np.random.randn()创建一个服从标准正态分布的多维数组:

n = np.random.randn()
print(n)
n = np.random.randn(5)
print(n)
n = np.random.randn(3, 4)
print(n)

使用 np.random.normal()创建一个服从正态分布的多维数组:

n = np.random.normal(loc=10, scale=1, size=(2, 3))
print(n)  # 均值:10,标准差:1,数组形状:2 行 3 列

使用 np.random.random()创建一个元素为 [0, 1) 随机数的多维数组:

n = np.random.random(size=(2, 3))
print(n)

使用 np.random.rand()也是创建一个元素为 [0, 1) 随机数的多维数组,只是参数传递方式不同,random.rand()接收分开的参数。

两个函数功能完全一样,NumPy 这么做可能是为了使 MATLAB 用户更容易学习 Python+NumPy 的组合。把其中一个函数去掉,所带来的麻烦远大于好处,因为有很多现存的代码使用了函数的不同版本。

数组属性

n = np.ones((3, 2), dtype=np.int8)
print(n.shape)  # 形状:(3, 2)
print(n.ndim)  # 维度:2
print(n.size)  # 总数据量:6
print(n.dtype)  # 元素类型:int8

基本操作

索引

n = np.array([1, 2, 3])
print(n[0], n[-1])  # 1 3
n = np.array([[1, 2, 3], [4, 5, 6]])
print(n[-1][-1], n[-1, -1])  # 6 6

切片

行切片:

n = np.array([1, 2, 3])
print(n[0:2])  # [1 2]
print(n[::-1])  # [3 2 1]

n = np.array([[1, 2], [3, 4], [5, 6]])
print(n[0])  # 取一行:[1 2]
print(n[0:2])
# 取连续行:# [[1 2]
#  [3 4]]

print(n[[0, 2]])
# 取不连续行:# [[1 2]
#  [5 6]]

列切片:

n = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
print(n[:, 0])  # 取一列,取所有行,第 0 列:[1 4 7]
print(n[:, 0:2])
# 取连续列:# [[1 2]
#  [4 5]
#  [7 8]]

print(n[:, [0, 2]])
# 取不连续列:# [[1 3]
#  [4 6]
#  [7 9]]

行翻转(上下翻转)和列翻转(左右翻转):

n = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
print(n[::-1])
# 行翻转
# [[7 8 9]
#  [4 5 6]
#  [1 2 3]]

print(n[:, ::-1])
# 列翻转
# [[3 2 1]
#  [6 5 4]
#  [9 8 7]]

数组变形

n = np.array([1, 2, 3, 4, 5, 6])
n2 = np.reshape(n, (2, 3))  # 2 行 3 列
n3 = n.reshape((2, 3))  # 2 行 3 列
n4 = n3.reshape(6)  # 变成一维,也可以写成 reshape(-1)
n5 = n.reshape(2, -1)  # - 1 表示任意剩余维度长度

数组合并

n1 = np.array([[1, 2, 3], [4, 5, 6]])
n2 = np.array([[7, 8, 9], [10, 11, 12]])
n3 = np.concatenate((n1, n2), axis=1)  # 默认上下合并,axis= 1 左右合并
n4 = np.hstack((n1, n2))  # 水平合并,即左右合并
n5 = np.vstack((n1, n2))  # 垂直合并,即上下合并

数组拆分

n = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
n2 = np.vsplit(n, 3)  # 垂直拆分,平均拆成 3 份,水平拆分 hsplit()
n3 = np.vsplit(n, (1,))  # 按照指定位置拆成
n4 = np.split(n, 3, axis=1)  # 默认垂直拆分,axis= 1 水平合并

数组排序

  • np.sort():不改变原数组,占内存空间
  • ndarray.sort():改变原数组,不多占内存空间
n = np.array([2, 44, 5, 3, 8])
n2 = np.sort(n)  # 默认 axis= 1 按行排序,axis= 0 按列排序
n.sort()
print(n, n2)

拷贝

n = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
n2 = n.copy()  # 深拷贝

聚合函数

n = np.array([[1, 2, 13], [4, 15, 6], [17, 8, 9]])

print(" 求和:", n.sum())
print(" 求和:", n.sum(axis=0))  # 每一列多行求和
n = np.array([1, 2, 3, np.nan])
print(np.nansum(n))  # 有 nan(not a number)值时,sum 无法求出和,要用 nansum,它会排除掉 nan 之后再求和

print(" 最小值:", n.min())
print(" 最大值:", n.max())
print(" 平均值:", n.mean())
print(" 中位数:", np.median(n))
print(" 百分位数:", np.percentile(n, 25))
print(" 极差:", n.ptp())

print(" 第一个最大值下标:", n.argmax())
print(" 按条件找到所有最大值下标:", np.argwhere(n == n.max()))

print("3 次方:", np.power(n, 3))

print(" 方差:", n.var())
print(" 标准差:", n.std())

print(" 对数:", np.log(n))

print(" 减法:", np.diff(n))  # 计算数组中相邻元素之间差值

print(" 符号:", np.sign(n))  # 值 >0,返回 1;值 <0,返回 -1;值 =0,返回 0

n = np.array([1, 2, 13])
weights = np.array([0.1, 0.2, 0.3])
print(" 加权平均:", np.average(n, weights=weights))

矩阵操作

算术运算

n = np.array([[11, 12, 13], [24, 15, 26], [17, 38, 39]])
print(n + 10)  # 加
print(n - 10)  # 减
print(n * 10)  # 乘
print(n / 10)  # 除
print(n // 10)  # 整除
print(n % 2)  # 余数
print(n**2)  # 次方

线性代数

矩阵积:第一个矩阵的列数 = 第二个矩阵的行数。

n1 = np.array([[1, 2, 3], [4, 5, 6]])
n2 = np.array([[1, 2], [3, 4], [5, 6]])
print(np.dot(n1, n2))

其他矩阵操作:

n = np.array([[1, 2], [4, 5]])
print(np.linalg.inv(n))  # 矩阵逆
print(np.round(np.linalg.det(n)))  # 矩阵行列式
print(np.linalg.matrix_rank(n))  # 矩阵的秩(满秩矩阵、奇异矩阵)

广播机制

ndarray 广播机制的两条规则:

  • 规则一:为缺失的维度补维度
  • 规则二:缺失元素用已有值填充
n1 = np.ones((2, 3), dtype=np.int8)
n2 = np.arange(3)
print(n1 + n2)
# 输出
# [[1 2 3]
#  [1 2 3]]

文件 IO 操作

数组保存和读取

NumPy 可以用二进制的格式保存数据。如果不想让别人看到数据,想使用 NumPy 时加载的话,那完全可以用这种方式来保存数据。

使用 save()来保存,保存的是一个以.npy 结尾的二进制文件。加载的时候,用 load()直接加载这个二进制数据文件。

row_string = "1, 10, 5, 2, 11, 22"
data = np.fromstring(row_string, dtype=np.int64, sep=",")
data = data.reshape(2, 3)
np.save("save_data.npy", data)

npy_data = np.load("save_data.npy")
print(npy_data)

NumPy 还可以使用 savez()将多个 array 保存到一个.npz 文件中。

train_data = np.array([1, 2, 3])
test_data = np.array([11, 22, 33])
np.savez("save_data.npz", train=train_data, test=test_data)

npz_data = np.load("save_data.npz")
print("train:", npz_data["train"])
print("test:", npz_data["test"])

用 savez()的时候,还有一个方法可以更节省空间,那就是用 savez_compressed()来做一次数据压缩。

np.savez_compressed("save_data.npz", train=train_data, test=test_data)

文本文件读写操作

data = np.array([1, 10, 5, 2, 11, 22])
np.savetxt("save_data.csv", data, delimiter=",", fmt="%s")

使用 np.loadtxt()就能自定义读取数据:

csv_data = np.loadtxt("save_data.csv", delimiter=",", dtype=np.int8)
print(csv_data)

loadtxt()传入的关键字参数:

  1. fname:文件名,数据类型为字符串
  2. delimiter:分隔符,数据类型为字符串
  3. usecols:读取列数,数据类型为元组, 其中元素个数有多少个,则选出多少列
  4. unpack:是否解包,数据类型为布尔。如果 True,读入属性将分别写入不同变量

高级函数

分段函数

简单分段,可以使用 where(condition, x, y),第一个参数表示条件,当条件成立时 where 方法返回 x,当条件不成立时 where 返回 y。

x = np.array([8, 9, -1, -6])
y = np.where(x > 0, x, np.abs(x))
print(y)  # [8 9 1 6]

分段数较多,可以用 select()。

x = np.array([8, 9, 0, -1, -6])
y = np.select([x < 0, x == 0, x > 0], [-1, 0, 1])
print(y)  # [1  1  0 -1 -1]

where()、select()函数的所有参数都需要在调用它们之前完成计算,在计算时还会产生许多保存中间结果的数组,因此如果输入的数组很大,将会发生大量内存分配和释放。

piecewise()解决了上述问题,它只计算需要计算的值。piecewise()是专门用于计算分段的函数。

x = np.array([8, 9, 5, 0, -1, -6])
y = np.piecewise(x, [x < 0, x == 0, x > 0], [-1, 0, 1])
print(y)  # [1  1  1  0 -1 -1]

正文完
 0
阿伯手记
版权声明:本站原创文章,由 阿伯手记 于2023-08-16发表,共计6019字。
转载说明:本站原创内容,除特殊说明外,均基于 CC BY-NC-SA 4.0 协议发布,转载须注明出处与链接。
评论(没有评论)
验证码

阿伯手记

阿伯手记
阿伯手记
喜欢编程,头发渐稀;成长路上,宝藏满地
文章数
767
评论数
207
阅读量
683736
今日一言
-「
热门文章
职场救急!AI请假话术生成器:1秒定制高通过率理由

职场救急!AI请假话术生成器:1秒定制高通过率理由

超级借口 不好开口?借口交给我!智能生成工作请假、上学请假、饭局爽约、约会拒绝、邀约推辞、万能借口等各种借口理...
夸克网盘快传助手提高非VIP下载速度

夸克网盘快传助手提高非VIP下载速度

夸克网盘限速这个大家都知道,不开会员差不多限速在几百 K。那有没有办法在合法合规途径加速下载夸克网盘呢?这里推...
TVAPP:开源电视盒子资源库,一键打造家庭影院

TVAPP:开源电视盒子资源库,一键打造家庭影院

导语 TVAPP 是一个专为 Android TV 电视盒子用户打造的开源影音资源库,集成了影视、直播、游戏等...
巴别英语:用美剧和TED演讲轻松提升英语听力与口语

巴别英语:用美剧和TED演讲轻松提升英语听力与口语

还在为枯燥的英语学习而烦恼吗?巴别英语通过创新的美剧学习模式,让英语学习变得生动有趣。平台提供海量美剧和 TE...
Chinese Name Generator 在线中文姓名生成器

Chinese Name Generator 在线中文姓名生成器

Chinese Name Generator 是一款在线中文姓名生成器,可在几秒内生成符合个人需求的中文名字。...
2025年12月 每日精选

2025年12月 每日精选

关于每日精选栏目 发现一些不错的资源,点击 这里 快速投稿。 12 月 26 日 .ax 顶级域 目前全球唯一...
123云盘限时福利:登录即送1个月VIP尊享权益!

123云盘限时福利:登录即送1个月VIP尊享权益!

🎁  零成本体验 20T 超大空间与会员加速通道 🎉 活动亮点 登录即送:无需任何复杂操作,登录账号直接领取 ...
最新评论
阿伯手记 阿伯手记 发了:https://aboss.top/moments/1064
吴蛋蛋 吴蛋蛋 快发小年快乐
吴蛋蛋 吴蛋蛋 Ask4Me,这个之前看server酱接入了
15220202929 15220202929 怎么用
八对 八对 麻烦大佬更新下【堆新】的友链站名:八对星星描述:极目星视穹苍无界•足履行者大地有疆链接:https://8dui.com图标:https://cf.8dui.com/logo.webp横标:https://cf.8dui.com/logo-w.webp订阅:https://8dui.com/rss.xml
三毛笔记 三毛笔记 已添加
DUINEW DUINEW 已添加贵站,期待贵站友链~博客名称:堆新博客地址:https://duinew.com/博客描述:堆新堆新,引力向新!——堆新(DUINEW)博客头像:https://d.duinew.com/logo.webp横版头像:https://d.duinew.com/logo-w.webp博客订阅:https://duinew.com/rss.xml
hedp hedp 没看懂
bingo bingo 直接生成就可以啦,也可以添加一些选项
热评文章
夸克网盘快传助手提高非VIP下载速度

夸克网盘快传助手提高非VIP下载速度

夸克网盘限速这个大家都知道,不开会员差不多限速在几百 K。那有没有办法在合法合规途径加速下载夸克网盘呢?这里推...
Short-Link 免费开源短网址程序,基于Fastify、Vercel和Supabase构建

Short-Link 免费开源短网址程序,基于Fastify、Vercel和Supabase构建

Short-Link 是一款基于 Fastify、Vercel 和 Supabase 构建的 URL 缩短服务...
清华大学官方免费DeepSeek教程

清华大学官方免费DeepSeek教程

AI 领域近期最引人注目的焦点当属 DeepSeek,这款由中国创新企业深度求索研发的人工智能工具,正以开放源...
Chinese Name Generator 在线中文姓名生成器

Chinese Name Generator 在线中文姓名生成器

Chinese Name Generator 是一款在线中文姓名生成器,可在几秒内生成符合个人需求的中文名字。...
2026年2月 每日精选

2026年2月 每日精选

关于每日精选栏目 发现一些不错的资源,点击 这里 快速投稿。 2 月 17 日 国家全民健身信息服务平台 过年...
DrawLink:一键生成链接视觉卡片,提升分享点击率

DrawLink:一键生成链接视觉卡片,提升分享点击率

小贴士 :此站或已变迁,但探索不止步。我们已为您备好「类似网站」精选合集,相信其中的发现同样能为您带来惊喜。
WebRTC Screen Mirror:基于浏览器免费开源投屏神器,可实现低延迟、跨平台屏幕共享

WebRTC Screen Mirror:基于浏览器免费开源投屏神器,可实现低延迟、跨平台屏幕共享

WebRTC Screen Mirror 是一款基于 WebRTC 技术的在线屏幕共享工具,它利用浏览器内置的...