目录
一、前言
二、为什么是Numpy?
?
三、科学计算库(Numpy)基础
3.0 list or ndarray?
3.1 先创建一个ndarray阵列
(1)由 串列&元组 生成
(2)由Numpy中的普通函式创建(arange、ones、zeros等)
(3)由Numpy中的随机函式创建(random.rand)
3.2 ndarray的那些属性
(1)a.ndim : 阵列的秩(维度总数)
(2)a.shape : 阵列形状 (矩阵:n行m列)
(3)a.size : 阵列总个数
(4)a.dtype : 元素型别
3.3 索引切片(与串列相似)
3.4 统计函式(求和,均值,方差,极值,中位数)
3.5 开始变换维度&型别!
(1)a.reshape(shape) : 回传一个shape形状的阵列
(2)a.flatten() : 对阵列降维折叠成一维阵列
(3)a.swapaxes(ax1,ax2) : 将阵列n个维度中两个维度进行调换
(4)a.astype(type) : 根据型别创建一个新的阵列
(5)a.tolist() : 重回串列
3.6 Numpy运算函式
(1)np.abs(x) : 计算阵列各元素的绝对值
(2)np.sqrt(x) : 计算阵列各元素的平方根
(3)np.square(x) : 计算阵列各元素的平方
(4)np.log(x) : 计算阵列各元素的自然对数
(5)np.ceil(x) np.floor(x) : 计算阵列各元素的ceiling值、floor值
(6)np.sin(x) np.cos(x) np.tan(x) : 计算阵列各元素的三角函式
(7)np.exp(x) : 计算阵列各元素的指数值
总结
一、前言
本人2020级本科生,坐标北京师范大学,主修人工智能,辅修教育学,在期末周来临之前萌在CSDN上发文章的想法,这样做的理由有两点,一方面可以在学习的同时归纳总结加深记忆,便于自己今后复习回顾;另一方面可以在CSDN这样的技术交流平台上留下自己的痕迹,记录AI人求学路上点滴的成长碎片,
这篇文章即是我在CSDN上发布的“Hello world”项目,希望日后回顾于此能有一些感慨触动,
二、为什么是Numpy?
作为一个AI科研人,在学习了Python,C,C++,R之后,Python在我的心中就是神一般的存在,我甚至很难想象如果没有Python的帮助,当代科研的进度会变慢多少,至少在我看来,身边的老师、师兄师姐几乎都只用Python作为自己的学习科研工具,这也侧面体现出Python在当今计算机科研领域的统治地位,
AI院第一个学期的专业必修课就是Python,这使它成为了我所了解与掌握的第一门语言,我对它保持热情至今,这也是本篇文章中我将使用的编程语言,
那么为何众多的工具库中选择了Numpy呢?主要是由于Numpy高速而便捷的矩阵处理模式将计算机领域与数学应用领域联系了起来,影像的矩阵变换,高维阵列操作均可以在Numpy中得到实作,并且2022年寒假美赛将至,对于AI人而言,熟练掌握Numpy科学计算库也可以和Matlab形成互补,(之前看过北理工嵩天老师的Mooc,讲解的很详细,不过由于缺乏实际操作,记忆丢失的很快,真正需要用到的时候才发现总结回顾真的很重要,这样可以避免花费大量的无效时间做一件日后回想不起来的事情)
这就是选择Numpy的原因,
附:Python之禅(隐藏彩蛋)
import this
The Zen of Python, by Tim Peters
Beautiful is better than ugly.
Explicit is better than implicit.
Simple is better than complex.
Complex is better than complicated.
Flat is better than nested.
Sparse is better than dense.
Readability counts.
Special cases aren't special enough to break the rules.
Although practicality beats purity.
Errors should never pass silently.
Unless explicitly silenced.
In the face of ambiguity, refuse the temptation to guess.
There should be one-- and preferably only one --obvious way to do it.
Although that way may not be obvious at first unless you're Dutch.
Now is better than never.
Although never is often better than *right* now.
If the implementation is hard to explain, it's a bad idea.
If the implementation is easy to explain, it may be a good idea.
Namespaces are one honking great idea -- let's do more of those!
(原文链接:https://blog.csdn.net/gzlaiyonghao/article/details/2151918)
演示环境:Jupyter Notebook(anaconda)
三、科学计算库(Numpy)基础
3.0 list or ndarray?
如果有一个串列 a = [1,2,3],你想完成全体元素+1的操作应该怎么办?
串列操作中 "a = a+1" 是不被允许的,编译器会提示报错信息,
numpy的出现解决了这个问题:
a=[1,2,3]
a=np.array(a)+1
array([2, 3, 4])
打印 a 的值,发现元素的确被执行了遍历操作,但同时,资料型别变成了 numpy.ndarray,
在Numpy中如果对阵列执行一个四则运算,就相当于要对其每一元素做相同的操作;如果阵列操作的物件和它的规模一样,则其结果就是对应位置进行计算,(广播机制)
ndarray 是 Numpy 中的底层资料结构,也是后续我们处理的物件,
虽然就目前这个例子而言,我们貌似并没有看出它强大的功能,但是如果当你像我一样有过影像处理、高维阵列变换这些实际经历之后,你会想重新再学习它一遍的,
干货分割线
3.1 先创建一个ndarray阵列
(1)由 串列&元组 生成
x=np.array(list/tuple,dtype=np.float32)
当不指定dtype时,Numpy将根据资料情况关联一个dtype型别,
热知识:在ndarray中所有元素必须是同一型别,否则会自动向下转换:int ---> float ---> str
(2)由Numpy中的普通函式创建(arange、ones、zeros等)
np.arange(a,b,c) : 类似 range 函式
np.arange(1,8)
array([1, 2, 3, 4, 5, 6, 7])
np.ones(shape) : 根据shape生成全1阵列(shape是元组型别!) 可指定dtype
np.ones((2,3))
array([[1., 1., 1.],
[1., 1., 1.]])
np.zeros(shape) : 根据shape生成全0阵列(shape是元组型别!) 可指定dtype
np.zeros((2,3))
array([[0., 0., 0.],
[0., 0., 0.]])
np.full(shape,val) : 根据shape生成一个用val填充的阵列
np.full((2,3),5)
array([[5, 5, 5],
[5, 5, 5]])
np.eye(n) : 创建一个 n*n 的单位矩阵(对角线为1,其余为0)
np.eye(3)
array([[1., 0., 0.],
[0., 1., 0.],
[0., 0., 1.]])
np.ones_like(a) : 根据阵列a的形状生成一个全1阵列
np.zeros_like(a) : 根据阵列a的形状生成一个全0阵列
np.full_like(a,val) : 根据阵列a的形状生成一个阵列,每个元素值都是val
np.linspace() : 根据起止资料等距填充,形成阵列
np.concatenate() : 将两个或多个阵列合并成一个新的阵列
(3)由Numpy中的随机函式创建(random.rand)
np.random.rand(d1,d2,d3...) : rand函式根据给定维度生成[0,1)之间的资料,包含0,不包含1
np.random.rand(2,3)
array([[0.95969572, 0.09220864, 0.43077609],
[0.94383599, 0.81581984, 0.74196641]])
np.random.randn(d1,d2,d3...) : randn函式回传一个或一组样本,具有标准正态分布,
np.random.randint(low,high,size) : 根据size回传随机整数,范围区间为[low,high),
3.2 ndarray的那些属性
冷知识:ndarray 在程序中的别名是 array
轴(axis):保存资料的维度
秩(rank):轴的数量
(1)a.ndim : 阵列的秩(维度总数)
a=np.array([[1,2,3],[4,5,6]])
a.ndim
2
(2)a.shape : 阵列形状 (矩阵:n行m列)
a.shape
(2, 3)
(3)a.size : 阵列总个数
a.size
6
(4)a.dtype : 元素型别
a.dtype
dtype('int32')
bool : 布尔型别(True & False)
int c,int p
int 8,int 16,int 32,int 64 有符号整型
uint 8,uint 16,uint 32,uint 64 无符号整型 [0,255]
float 16,float 32,float 64 半精度浮点数
complex 64,complex 128 复数型别
3.3 索引切片(与串列相似)
此处直接参考嵩天老师的PPT,阵列索引切片这个部分还是比较easy的,
补充:bool 索引(阵列条件判断时可用)
a=np.random.rand(10)
a>0.5
np.where(a>0.5)
array([ True, False, True, False, True, False, True, True, True,
True])
(array([0, 2, 4, 6, 7, 8, 9], dtype=int64),)
a[a>0.5]
a[np.where(a>0.5)]
np.logical_and(a[a>0.5],a[np.where(a>0.5)])
array([0.80976535, 0.74469848, 0.55484932, 0.75266807, 0.606097 ,
0.67212678, 0.68324472])
array([0.80976535, 0.74469848, 0.55484932, 0.75266807, 0.606097 ,
0.67212678, 0.68324472])
array([ True, True, True, True, True, True, True])
3.4 统计函式(求和,均值,方差,极值,中位数)
3.5 开始变换维度&型别!
(1)a.reshape(shape) : 回传一个shape形状的阵列
a=np.random.rand(2,4)
a
a=a.reshape((4,2))
a
array([[0.92403131, 0.60942285, 0.24788947, 0.64300871],
[0.5516135 , 0.46864957, 0.14285288, 0.64345045]])
array([[0.92403131, 0.60942285],
[0.24788947, 0.64300871],
[0.5516135 , 0.46864957],
[0.14285288, 0.64345045]])
冷知识:reshape方法保持原阵列不变,resize方法改变原阵列,
(2)a.flatten() : 对阵列降维折叠成一维阵列
a
b=a.flatten()
b
array([[0.92403131, 0.60942285],
[0.24788947, 0.64300871],
[0.5516135 , 0.46864957],
[0.14285288, 0.64345045]])
array([0.92403131, 0.60942285, 0.24788947, 0.64300871, 0.5516135 ,
0.46864957, 0.14285288, 0.64345045])
冷知识:flatten方法保持原阵列不变
(3)a.swapaxes(ax1,ax2) : 将阵列n个维度中两个维度进行调换
(4)a.astype(type) : 根据型别创建一个新的阵列
a=np.random.randint(2,8,size=(3,3))
a
a.dtype
b=a.astype(np.float)
b
b.dtype
array([[5, 4, 2],
[4, 3, 6],
[7, 5, 4]])
dtype('int32')
array([[5., 4., 2.],
[4., 3., 6.],
[7., 5., 4.]])
dtype('float64')
(5)a.tolist() : 重回串列
a=np.full((2,3,4),25,dtype=np.int)
a
b=a.tolist()
b
array([[[25, 25, 25, 25],
[25, 25, 25, 25],
[25, 25, 25, 25]],
[[25, 25, 25, 25],
[25, 25, 25, 25],
[25, 25, 25, 25]]])
[[[25, 25, 25, 25], [25, 25, 25, 25], [25, 25, 25, 25]],
[[25, 25, 25, 25], [25, 25, 25, 25], [25, 25, 25, 25]]]
3.6 Numpy运算函式
热知识:阵列与标量的之间的运算作用于阵列的每一个元素
实体:计算 a 与元素平均值之间的商
a=np.arange(24).reshape(2,3,4)
a=a/a.mean()
a
array([[[0. , 0.08695652, 0.17391304, 0.26086957],
[0.34782609, 0.43478261, 0.52173913, 0.60869565],
[0.69565217, 0.7826087 , 0.86956522, 0.95652174]],
[[1.04347826, 1.13043478, 1.2173913 , 1.30434783],
[1.39130435, 1.47826087, 1.56521739, 1.65217391],
[1.73913043, 1.82608696, 1.91304348, 2. ]]])
(1)np.abs(x) : 计算阵列各元素的绝对值
(2)np.sqrt(x) : 计算阵列各元素的平方根
(3)np.square(x) : 计算阵列各元素的平方
(4)np.log(x) : 计算阵列各元素的自然对数
冷知识:np.log10(x) : 10底对数 np.log2(x) : 2底对数
(5)np.ceil(x) np.floor(x) : 计算阵列各元素的ceiling值、floor值
(6)np.sin(x) np.cos(x) np.tan(x) : 计算阵列各元素的三角函式
(7)np.exp(x) : 计算阵列各元素的指数值
总结
本篇文章对Numpy科学计算库的基础知识做了一个系统的整理,从一个简单的问题引出了串列和阵列的操作差异,接着按照 阵列的创建方式、 阵列的属性、 阵列的切片方法、 阵列的统计函式、 阵列的维度型别变换、 阵列的运算函式 这一逻辑顺序回顾了 Numpy 的基本操作,
下一次更新的内容将会以常用功能为导向,对Numpy进行一个扩展延续,从实践的层面加深对Numpy的认知,
0 评论