The Basics部分
英文官方教程链接
https://numpy.org/doc/stable/user/quickstart.html
numpy的主要对象是同构多维数组,我理解的同构就是元素类型相同。numpy中的维度叫做axe,百度译为斧头,不过应该叫轴(可能我没查准确)。
#以下都是再pycharm终端的显示,因为我基本不使用python的IDLE,
#我安装python只是因为pycharm要配置项目编辑器,也就是环境。
[1 2 3] #1维,我平常也是用维来称它,不习惯用轴,
#不过轴的称法也很形象,至少有助于理解小于3维的numpy数组
[[1 2 3]
[1 2 3]] #2维,每一维有3个元素
我觉得比较直观的看numpy数组的维数可以看最开始有几个“[”。
numpy里的数组和python中的列表很像,但是区别还是挺大的。numpy现在多用于科学计算和人工智能。它的数组叫做ndarray(不过我平常用的是numpy.array),有如下属性:ndim,shape,size,dtype,itemsize,data(这些再python的list里面没有)。标红的是我觉得比较常用的。
import numpy as np
a = np.arange(6).reshape(2,3)
#arange用法和python中的range一样
#reshape叫做重塑,第1维里有两个元素[···]和[···],第2维有3个例如[0 1 2]
print(a)
#[[0 1 2]
# [3 4 5]]
print(a.shape)
#(2,3),返回的是一个元组
#shape可以形象地解释为形状,就是逐个看每个“[]”里有几个元素
print(a.ndim)
#2
#ndim就是一共有几维
print(a.dtype)
#int32
#数据的类型,再创建数组时候可以指定,例如np.array([1,2,3],dtype=float)
#例子的结果是[1. 2. 3.],numpy中小鼠后的0一般省略不显示
print(a.itemsize)
#4
#因为int32数据类型占有字节数为4,上面例子float类型数据类型字节数就是8
print(a.size)
#6
#尺寸,可以狭隘地理解为去除层层包装后有多少个元素
用np.array创建数组时,括号里面得是python的列表或元组,不能是简单的数字凭借,原因就是它是一个函数,参数不是简单的数字。
import numpy as np
b = np.array((1,2,3),dtype=float)
#这次我用的就是元组
#像这样就会报错:b = np.array(1, 2, 3, 4)
c = np.array([(1,2,3),(4,5,6)])
print(c)
#[[1 2 3]
# [4 5 6]]
和python一样,numpy的数据类型也有复数形式。
import numpy as np
c = np.array([[1, 2], [3, 4]], dtype=complex)
print(c)
#[[1.+0.j, 2.+0.j]
# [3.+0.j, 4.+0.j]] 虚部有j就是复数
一些常用的数组,一般用在不知道数据的情况下,后续只要用运算操作将值改变即可。可以简单理解为定义一个初始化数组。
import numpy as np
a = np.zeros((2,3))
print(a)
#[[0. 0. 0.]
# [0. 0. 0.]] 个人认为这个创建全0数组最常用,默认为float型
b = np.ones((2,3))
print(b)
#[[1. 1. 1.]
# [1. 1. 1.]]
c = np.empty((2,3))
print(c)
#[[1. 1. 1.]
# [1. 1. 1.]] 如果紧接着和前面的结构一样容易受影响,不是我们要的结果
#具体原因我也不是很清楚
d = np.empty((2,2))
print(d)
#[[1.97109087e-268 1.19574338e-311]
# [3.63820323e-249 1.19574338e-311]]
#这才是我们想要的,它的作用是随机生成近乎0的数,采用科学计数法
#我觉得这个可以用作神经网络里的偏差bias
最值得一体的就是它的运算操作了,其中最特殊的就是广播机制,他会根据大的数据类型来调整小的。运算太多,列不过来了,有兴趣的或是需要的后辈、同辈、前辈可以自己到官网查询
import numpy as np
a = np.array([2,3,4])
b = np.array([2])
print(a+b)
#[4 5 6]
#所谓广播就是元素扩充,扩成大的数组的形状。
print(a/b)
#[1. 1.5 2.] 除法是浮点数运算
print(b-a)
#[0 -1 -2]
#但是b = np.array([2,2])就会报错,因为他不会广播了,
#我想可以这样理解,广播就是将数据横向或纵向复制连接
#第二种情况无论往哪个方向都无法得到大的数组a的形状,所以报错
c = np.array([2,2,2])
print(a*c)
#[4 6 8] 对应相乘
print(a@c)
print(a.dot(c))
#18 都是矩阵乘法
print(a.T)
#[2 3 4] 转置,虽然这个原样显示了,但其实已经转置过了,用高维数组就可以看出来了
print(a.sum)
#9 .max .min .sum和python中列表操作很像,我就不展示了
d = np.array([[1,2,3],[2,3,4]])
print(d.sum(axis=0))
#[3 5 7] 按照第0维相加
#维度是从0开始的
print(d.sum(axis=1))
#[6 9] 按照第1维相加
print(np.exp(b))
#[7.3890561] 数学中e的2次方
print(np.sqrt(b))
#[1.41421356] 数学中2的平方根
和python的列表一样,numpy数组也有切片操作,切片操作可以参考python官方教程,不过它针对每一维。
import numpy as np
a = np.array([[1,2,3],[2,3,4],[3,4,5]])
print(a[:,0:2])
#[[1 2]
# [2 3]
# [3 4]]
#第一维取所有,第二维取0到1
展平数组操作。类似于深度学习里面的x.flatten(),x是张量。这个挺有用的。
import numpy as np
a = np.array([[1,2,3],[2,3,4]])
print(a.ravel())
#[1 2 3 2 3 4] 展平
重构,一定要保证重构得起来。直观点说就是,shape元组里面的数乘起来和原来不变。这里可不存在什么广播,因为它不知道怎么给你添元素,最主要的是不一定复制连接后就可以保证元素不多不少。以下对reshape的运作方式有些疑问,敬请各位指导。另外,要注意reshape和resize的区别,前者相当于先复制一份再重构并返回,原来的对象不变;后者是对操作对象本身的重构,即本身以改变了。这在深度学习里要注意。
import numpy as np
a = np.array([[1,2,3],[2,3,4]])
print(a.shape)
#(2,3)
b = a.reshape(3,2) #返回a的重构,不改变a
print(a.resize(3,2)) #对a本身的重构,a已变
print(b.shape)
#(3,2)
print(b)
#[[1 2]
# [3 2]
# [3 4]]
#怎么变得我现在也不是太明白,不过可以看出,他是按照0维3个元素,1维2个元素
#然后依次抽取元素填空
要想将不同的数组像字符串一样拼在一起怎么办呢?(下面的方法不增加维度,增加维度的有点难,不见得一定用得到,所以我就不例举了,可以参见官网)
import numpy as np
a = np.array([[1,2],[1,2]])
b = np.array([[3,2],[3,6]])
print(np.vstack((a,b)))
#[[1 2]
# [1 2]
# [3 2]
# [3 6]] 垂直堆砌,vstack里的v代表垂直,stack堆砌
print(np.hstack((a,b)))
#[[1 2 3 2]
# [1 2 3 6]],水平堆砌,h水平
#更高维的我就不试了,太复杂,我有点理解不了
深度拷贝
import numpy as np
a = np.array([[1,2,3],[2,3,4]])
b = a.copy()
print(b is a)
#False 虽然进行拷贝,但已经不是同一个了,复制的就是复制的,绝不是本体
#这样,对b的resize这种改变本身的操作就不会影响到a了