这是我人生中第一次在csdn发布动态,希望能坚持下去,好好学习,好好做笔记,好好准备比赛,不负儿时梦~~
因为这篇文章是一边看几篇文章一边写的,所以可能会很相似,我没有侵权的意图,也不是教别人怎么用numpy,仅仅是个人学习记录,侵删~
那么首先我想了解一下numpy究竟是干什么的,于是我在csdn上看了好几篇的教程。首先它是python的第三方库,主要做的就是有关数组的运算,尤其是多维的数组,而且有方便的矩阵运算。这样的话,在处理大量数据和做分析的时候应该会方便很多。
安装啥的就略过了,因为我是python初学者,之前学过c和c++,所以会类比来学习python。
首先使用numpy
import numpy as np
这就将这个库引用了,而且起了别名为np,在之后的很多操作都需要声明像定义域一样的东西,总是numpy.numpy.的,所以别名很重要。
1.创建数组:
np.array([1,2,3])
np.array([[1,2,3],[4,5,6]])
np.array([[[1,1,1],[1,1,1]],[[2,2,2],[2,2,2]]])
np.zeros((3,4))
np.ones((3,4))
np.full((3,4),2)
np.arange(10)
np.arange(10).reshape(2,5)
np.eye(3,dtype=np.int64)
np.random.rand(2,3)
np.random.randint(0,11,(3,4))
这个比较简单,使用np中的array函数,以上分别创建了一维、二维、三维数组。使用zeros或者ones就可以创建不同维度的全0或者全1数组,也可以直接用full来创建并填充。(注意维度那个参数要用括号括住)
其实array还可以设置类型、排列方式、返回最低维度等参数,用的时候可以查阅。
像python中的range一样创建就可以用arange创建一维的,然后用reshape来换维度。
用eye可以创建单位矩阵,可以设置类型。如下的:
[1,0,0]
[0,1,0]
[0,0,1]
关于随机数组的创建。可以用np.random中的函数,其中rand本来是生成一个0到1的浮点数,但里面可以带数组的尺寸,来生成随机数组(注意这里不用带括号,可能是因为没有别的参数了)。然后randint参数就多点,可以生成从a到b的整数(包括a但不包括b),后面跟括号可以带数组尺寸,生成随机数组。
b = [[1,2,3],[4,5,6],[7,8,9]]
a = np.asarray(b)
print(a)
[[1 2 3]
[4 5 6]
[7 8 9]]
想要将python中的序列转换成numpy的数组就可以用np.asarray
a = np.linspace(start, stop, num=50, endpoint=True, retstep=False, dtype=None)
a = np.logspace(start, stop, num=50, endpoint=True, base=10.0, dtype=None)
创建等差和等比数列可以用linspace和logspace
2数组的运算:
a.求和运算
a = np.arange(1,10).reshape(3,3)
print(a)
print()
print(np.sum(a,axis=0))
print(np.sum(a,axis=1))
print(np.sum(a[...,2],axis=0))
print(np.sum(a[0,...],axis=0))
[[1 2 3]
[4 5 6]
[7 8 9]]
[12 15 18]
[ 6 15 24]
186
使用np中的sum可以对数组求和,其中axis确定求和的轴,再利用切片操作,可以实现对某一行或者某一列求和。上述的操作分别是按行求和,按列求和,第三列求和,第一行求和。
当然,很多操作是有两种方式的,一种是用np来调用,另一种是用类成员函数来调用。(本文采用np调用的形式,后续就不再说明了)
np.sum(a,axis=0)
a.sum(axis=0)
b.求平均值
a = np.arange(1,10).reshape(3,3)
print(a)
print(np.mean(a))
[[1 2 3]
[4 5 6]
[7 8 9]]
5.0
直接调用mean函数就可以了。
c.复制拼接
a = np.array([[1,2],[3,4]])
print(np.tile(a,(2,2)))
print(a)
[[1 2 1 2]
[3 4 3 4]
[1 2 1 2]
[3 4 3 4]]
[[1 2]
[3 4]]
tile函数可以创建数组赋值再拼接的副本,可以自己设定维度,这个操作不会改变原数组。其实也是一种广播的形式。
d.数组排序(arg和直接形式)
a = np.array([[5,2,7],[4,3,1],[8,9,6]])
print(a)
print()
print(np.argsort(a))
print()
print(np.argsort(a,axis=0))
[[5 2 7]
[4 3 1]
[8 9 6]][[1 0 2]
[2 1 0]
[2 0 1]][[1 0 1]
[0 1 2]
[2 2 0]]
用np.argsort()可以对数组进行排序,默认是按最低维度排序,可以自定维度。然后返回每个元素对应的下标。此处设想,要对所有数进行排序,应该可以先把数组用reshape生成一维副本(也可以用成员函数flatten),然后排序。
a = np.array([[5,2,7],[4,3,1],[8,9,6]])
print(np.sort(a))
[[2 5 7]
[1 3 4]
[6 8 9]]
np.sort()就不是返回下标,而是返回按特定轴排序好的数组。
e.找数组的最大值(arg和a形式)
a = np.array([[5,2,7],[4,3,1],[8,9,6]])
print(a)
print()
print(np.argmax(a))
print(np.argmax(a,axis=1))
print(np.argmax(a,axis=0))
[[5 2 7]
[4 3 1]
[8 9 6]]7
[2 0 1]
[2 2 0]
如上,调用np.argmax()会返回原数组折叠成一维的时候最大值的下标,可以按行按列找最大值,也是返回一系列的下标 (min是同理的,就不说了)。
a = np.array([[5,2,7],[4,3,1],[8,9,6]])
print(np.amax(a))
9
如上所示,np.amax()直接返回了最大值(最小值同理)。
f.四则运算
a = np.array([[1,2],[3,4]])
b = a
print(a)
print(b)
print(a+b)
print(a-b)
print(a*b)
print(a/b)
[[1 2]
[3 4]]
[[1 2]
[3 4]]
[[2 4]
[6 8]]
[[0 0]
[0 0]]
[[ 1 4]
[ 9 16]]
[[1. 1.]
[1. 1.]]
可以看到,相同尺寸的数组(不广播)进行四则运算直接用运算符就可以了。
类似的操作还有如下:
print(a+2)
print(a-2)
print(a*2)
print(a/2)
g.矩阵操作
a = np.array([[1,2],[3,4]])
b = a
print(np.dot(a,b))
a = np.mat(a)
b = np.mat(b)
print(a*b)
[[ 7 10]
[15 22]]
[[ 7 10]
[15 22]]
矩阵乘法:一般来说直接用*号就是让两个数列的对应数相乘,如果是想要矩阵乘,就要用np.dot()函数。另外,如果直接说明了数组是矩阵,用np.mat()创建副本,就可以直接用*来矩阵乘。
a = np.array([[1,2],[3,4]])
print(a)
print()
print(a.T)
[[1 2]
[3 4]][[1 3]
[2 4]]
成员函数T就可以生成数组的转置副本。
3.numpy数组的索引和切片操作:
a.指定范围的切片
a = np.array([[1,2,3],[4,5,6],[7,8,9]])
print(a[0:2,...])
print(a[...,0:2])
[[1 2 3]
[4 5 6]]
[[1 2]
[4 5]
[7 8]]
跟python一样用冒号分隔始末端点(包括前面不包括后面),再用逗号分隔开维度,维度从高到低。
b.布尔数组和布尔切片
a = np.array([[1,2,3],[4,5,6],[7,8,9]])
print(a>3)
print(a[a>3])
[[False False False]
[ True True True]
[ True True True]]
[4 5 6 7 8 9]
直接用数组来作为表达式的话就会对数组中的每一个元素进行判定,然后返回由True和False组成的数组。如果在切片的位置用数组构成表达式那么返回每个满足的元素构成的一维数组。
4.数据类型:
np中定义了很多种数据类型,规定不同的内存大小,可以自行查看。
对数组用dtype可以查看数据类型。
a = np.array([[1,2,3],[4,5,6],[7,8,9]])
print(a.astype(np.float32))
print(a)
[[1. 2. 3.]
[4. 5. 6.]
[7. 8. 9.]]
[[1 2 3]
[4 5 6]
[7 8 9]]
使用astype成员函数可以转换数组的数据类型,并创建一个副本。
5.关于numpy数组的遍历:
a = np.array([[1,2,3],[4,5,6],[7,8,9]])
for i in a:
print(i)
for i in np.nditer(a):
print(i,end=' ')
print()
for i in a.flat:
print(i,end=' ')
[1 2 3]
[4 5 6]
[7 8 9]
1 2 3 4 5 6 7 8 91 2 3 4 5 6 7 8 9
可以看出,直接用for遍历会默认按照最高维度来遍历数组,而不是一个一个。用numpy的nditer生成迭代器就可以一个一个遍历数组了。也可以用ny.ndarray.flat生成一维迭代器。
a = np.array([[1,2,3],[4,5,6],[7,8,9]])
for i in np.nditer(a,order='F'):
print(i,end=' ')
print()
for i in np.nditer(a.copy(order='F')):
print(i,end=' ')
1 4 7 2 5 8 3 6 9
1 4 7 2 5 8 3 6 9
默认的情况下,遍历的顺序是C风格的,可以更改order参数来转成F风格。可以对nditer更改,也可以对原数组的副本进行更改。
nditer还有一个可选参数op_flags[],有readonly,writeonly,readwrite可以选择,字面意思。
6.numpy数组的相关操作(增删拼接等,数轴旋转知道就行,之后用的时候再查)
以下的增删操作可以结合切片完成复杂效果。
a.修改数组尺寸
a = np.array([1,2,3])
a.resize((3,3))
print(a)
a = np.array([1,2,3])
a = np.resize(a,(3,3))
print(a)
[[1 2 3]
[0 0 0]
[0 0 0]]
[[1 2 3]
[1 2 3]
[1 2 3]]
resize一个重新调整数组尺寸的函数,跟reshape不同的是它没有返回值,直接对原数组进行修改。有意思的是np.ndarray.resize不会进行广播,而np.resize会广播。
b.末尾追加数组元素(append)
a = np.array([[1,2,3],[4,5,6]])
print(np.append(a,[1,1,1]))
print(np.append(a,[[1,1,1]],axis=0))
print(np.append(a,[[1,1,1],[1,1,1]],axis=1))
print(a)
[1 2 3 4 5 6 1 1 1]
[[1 2 3]
[4 5 6]
[1 1 1]]
[[1 2 3 1 1 1]
[4 5 6 1 1 1]]
[[1 2 3]
[4 5 6]]
调用np.append来增加数组的元素并返回副本。默认情况下将原数组展开成一维,然后添加。可以修改添加的轴。(注意:二维数组按行添加,那添加的也是二维的数组。) 并且添加的时候要保证数组各轴的维度一致,元素不能多也不能少。
c.插入元素(insert)
a = np.array([[1,2,3],[4,5,6]])
print(np.insert(a,1,[0,1,0],axis=0))
[[1 2 3]
[0 1 0]
[4 5 6]]
np.insert(arr, obj, values, axis)
跟追加是很相似的,不给轴就默认展开成一维。这个是在索引之前插入的。如果给的元素维度不够也会进行广播。
d.删除元素(delete)
np.delete(arr, obj, axis)
基本和insert一样了,不用多说。
e.查找满足条件的元素并返回索引(argwhere)
a = np.array([[1,2,3],[4,5,6]])
print(np.argwhere(a>3))
[[1 0]
[1 1]
[1 2]]
表达式里都是用数组名字来代替数组内元素的。
f.去重(unique)
a = np.array([[1,2,3],[4,5,6],[1,2,3],[1,2,3]])
print(np.unique(a))
print(np.unique(a,return_index=1,return_inverse=1,return_counts=1))
[1 2 3 4 5 6]
(array([1, 2, 3, 4, 5, 6]),array([0, 1, 2, 3, 4, 5], dtype=int64),
array([0, 1, 2, 3, 4, 5, 0, 1, 2, 0, 1, 2], dtype=int64),
array([3, 3, 3, 1, 1, 1], dtype=int64))
numpy.unique(arr, return_index, return_inverse, return_counts)
unique会将给定的数组展开成一维数组,然后去重。可以返回多个数组。return_index返回新数组元素在原数组的索引,return_inverse返回原数组在新数组的索引,return_counts返回新数组中每个元素在原数组出现的次数。
g.连接(concatenate和stack)
a = np.array([[1,2],[3,4]])
b = np.array([[5,6],[7,8]])
print(np.concatenate((a,b),axis=0))
print(np.concatenate((a,b),axis=1))
print(np.stack((a,b)))
[[1 2]
[3 4]
[5 6]
[7 8]]
[[1 2 5 6]
[3 4 7 8]]
[[[1 2]
[3 4]][[5 6]
[7 8]]]
concatenate是沿原有轴来拼接数组,stack是按新轴来拼接。
h.分割数组(split)
numpy.split(ary, indices_or_sections, axis)
分割成特定数量,或者用列表设置断点。
说实话的,numpy真的很多很多很好用的函数,在这里我觉得我搬运不完,所以就记录以上的一些基本内容吧,其他的知道有就行,用的时候再去查阅。