二、numpy(十分基本)
导入模块
import numpy as np
基础操作
使用array或arange函数生成数组
a=np.array(range(10))
或者
a=np.arange(10)
可见,arange=array+range
numpy的数组类型
n维数组英文是ndarray
注:用numpy创建的数组内的所有数的数据类型都是相同的,都与设定的数组类型相同
bool_ | 布尔型数据类型(True 或者 False) |
---|---|
int_ | 默认的整数类型(类似于 C 语言中的 long,int32 或 int64) |
intc | 与 C 的 int 类型一样,一般是 int32 或 int 64 |
intp | 用于索引的整数类型(类似于 C 的 ssize_t,一般情况下仍然是 int32 或 int64) |
int8 | 字节(-128 to 127) |
int16 | 整数(-32768 to 32767) |
int32 | 整数(-2147483648 to 2147483647) |
int64 | 整数(-9223372036854775808 to 9223372036854775807) |
uint8 | 无符号整数(0 to 255) |
uint16 | 无符号整数(0 to 65535) |
uint32 | 无符号整数(0 to 4294967295) |
uint64 | 无符号整数(0 to 18446744073709551615) |
float_ | float64 类型的简写 |
float16 | 半精度浮点数,包括:1 个符号位,5 个指数位,10 个尾数位 |
float32 | 单精度浮点数,包括:1 个符号位,8 个指数位,23 个尾数位 |
float64 | 双精度浮点数,包括:1 个符号位,11 个指数位,52 个尾数位 |
complex_ | complex128 类型的简写,即 128 位复数 |
complex64 | 复数,表示双 32 位浮点数(实数部分和虚数部分) |
complex128 | 复数,表示双 64 位浮点数(实数部分和虚数部分) |
使用dtype来检查数组类型
用法如:
a=np.arange(10)
print(a.dtype)
结果为:
int32
更改数据类型
1、在array,arange中改,如
a=np.arange(10,dtype='float')
print(a)
print(a.dtype)
结果为:
[0. 1. 2. 3. 4. 5. 6. 7. 8. 9.]
float64
或
a=np.array(range(10),dtype='float')
print(a)
print(a.dtype)
结果相同
2、使用astype
a=np.array(range(10),dtype='float')
b=a.astype('int64')
print(b)
print(b.dtype)
结果如下:
[0 1 2 3 4 5 6 7 8 9]
int64
使用random创建数组
取小数:
a=np.array([random.random() for i in range(10)])
print(a)
结果为:
[0.36642786 0.06764821 0.13200947 0.7054274 0.43684297 0.17421986
0.70542854 0.14780838 0.25937034 0.99946342]
都是8位小数
如果想要取小数点后n位(不四舍五入)
如取两位:
a=np.array([random.random() for i in range(10)])
b=np.round(a,2)
结果为
[0.21 0.33 0.5 0.87 0.57 0.15 0.85 0.14 0.22 0.39]
换2为n即可实现取n位
创建大小在n到m之间的a行b列数组
np.random.randint(n,m(a,b))
伪随机生成
np.random.seed(10)
a=np.random.randint((a,b))
这样就会生成一个固定不变的a行b列数组
生成只有零的数组
np.zeros(shape,dtype,order)
shape后接形状(具体后面讲)
dtype后接类型
order后接C就按行排,接F就按列排
生成只有一的数组
np.ones(shape,dtype,order)
用法与zeros类似
使用eye生成矩阵
np.eyes(n)
会生成一个边长为n,对角线数值全为1,其他均为0的矩阵,如np.eye(5):
[[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.]]
查看数组形状
1、若为只有两次维度:
import numpy as np
a=np.array([[1,2,3],[4,5,6]])
print(a)
print(a.shape)
结果为:
[[1 2 3]
[4 5 6]]
(2, 3)
(2,3)表示该二维列表有一次维度级别两个(即以一层列表为界),3表示一次维度级别的每个有3个单个。这里也称有2行3列
(注意第几层是自内向外算的)
2、若最高为三次:
import numpy as np
a=np.array([[[1,2,3],[4,5,6]],[[7,8,9],[10,11,12]]])
print(a)
print(a.shape)
结果为:
[[[ 1 2 3]
[ 4 5 6]]
[[ 7 8 9]
[10 11 12]]]
(2, 2, 3)
(2, 2, 3)中第一个2表示该三维列表中二次维度级别的有2个(即以第二层列表为界),第二个2表二次维度级别的每个中的有一次维度级别2个(即以第一层列表为界),3表示一次维度级别内的每个中有3个单个数
·这里的第一个2在第三维度层面,第二个2在第二维度层面,3在第一维度层面
(注意第几层是自内向外算的)
最高为更高维度的以此类推
轴
如一维数组只有0轴对应(a,)
二维数组有0,1轴对应(a,b)
三维数组有0,1,2轴对应(a,b,c)
如图:[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-RkfRltkO-1666874569910)(C:\Users\10291\AppData\Roaming\Typora\typora-user-images\image-20221026115212732.png)]
所以轴可代表维度,维度的处理就是发生在该维度对应轴上的处理
注意:在n维数组中,axis=n-1(n-1轴)虽然水平,但是表示垂直(列)的变化;
axis=n(n轴)虽然是垂直,但是表示水平(行)的变化 (n>=2)
修改数组形状
import numpy as np
a=np.array([[1,2,3],[4,5,6]])
print(a)
print(a.reshape(3,2))
结果为:
[[1 2 3]
[4 5 6]]
[[1 2]
[3 4]
[5 6]]
可见从(2,3)变成(3,2)
还可以不同次维度修改(以最高为二次维度为例):
import numpy as np
a=np.array([[[1,2,3],[4,5,6]],[[7,8,9],[10,11,12]]])
print(a)
print(a.reshape(12,))
结果为:
[[[ 1 2 3]
[ 4 5 6]]
[[ 7 8 9]
[10 11 12]]]
[ 1 2 3 4 5 6 7 8 9 10 11 12]
可见发生了改变。
这个展开成一维数组的操作还有另一种方法:使用flatten()
import numpy as np
a=np.array([[[1,2,3],[4,5,6]],[[7,8,9],[10,11,12]]])
print(a)
print(a.flatten())
结果为:
[[[ 1 2 3]
[ 4 5 6]]
[[ 7 8 9]
[10 11 12]]]
[ 1 2 3 4 5 6 7 8 9 10 11 12]
注意:形状修改后,原数组并不会变
数组的计算
1、全体加某数
如:
import numpy as np
a=np.array([1,2,3,4,5,6,7,8,9,10,11,12])
b=a+5
print(b)
结果为:
[ 6 7 8 9 10 11 12 13 14 15 16 17]
多少维数组都可以用
2、数组与数组进行运算
(1)、相同形状数组运算:位置对应的数进行运算,
如:
import numpy as np
a=np.array([[1,2,3],[4,5,6]])
b=np.array([[2,3,4],[5,6,7]])
print(a+b)
结果为:
[[ 3 5 7]
[ 9 11 13]]
(2)、不相同形状且最高维度不同数组运算:把最高维度小的数组与最高维度高的数组的每一个等维度数组一一进行相同形状数组运算
如:
import numpy as np
a=np.array([[1,2,3],[4,5,6]])
b=np.array([2,3,4])
print(a+b)
结果为:
[[ 3 5 7]
[ 6 8 10]]
(3)、不相同形状且最高维度相同数组运算
以简单情况为例:
import numpy as np
a=np.array([[1,2,3],[4,5,6],[7,8,9],[10,11,12]])
b=np.array([[0],[1],[2],[3]])
print(a+b)
结果为:
[[ 1 2 3]
[ 5 6 7]
[ 9 10 11]
[13 14 15]]
(4)、典型报错(原因:不对应)
import numpy as np
a=np.array([[1,2,3],[4,5,6],[7,8,9]])
b=np.array([[1,2,3],[4,5,6]])
print(a+b)
结果:
ValueError: operands could not be broadcast together with shapes (3,3) (2,3)
其他情况大同小异
附广播原则:
如果两个数组的后缘维度(从末尾开始算起的维度)的轴长度相符或其中一方的长度为1,则认为它们是广播兼容的。广播会在缺失维度和(或)轴长度为1的维度上进行。
符合即可使用数组运算
从文件提取数据
1、提取数据
使用loadtxt进行提取,用法如下:
np.loadtxt(fnmae,dtype,delimiter,skiprows,usecols,unpack)
fname后接文件地址来导入文件
dtype后接想要的数据类型
delimiter后接符号用于用该符号分割每一列(默认为空格)
skiprows后接数字以表示跳过哪几列
usecols后接数字表示跳过哪几列
unpack后接True或False来表示是否进行转置
2、转置
即列变行,行变列
可用:
np.loadtxt(unpack=True)
或
a.swapaxes(1,0)
或
a.transpose()
a为任意二维数组
索引和切片
以二维数组为例
以下a为任意二维数组
取数
取单个数
a[n,m]
这样就取了第n+1行,第m+1列的那个数
取连续数
a[n,m:]
这样就取了第n+1行,第m+1列的那个数及后面的数
取不连续数
a[[n,m],[k,l]]
这样就取得了第n+1行,第k+!列和第m+1行,第l+1列的数
取行
取单行
a[n,:]
这样就提取了第n+1行,因为只有一行,自动变成一维数组
取连续行
a[n:m,:]
这样就变成从第n+1行开始取到提取
取不连续多行
a[[n,m,l],:]
这样就提取了第n+1行,第m+1行,第l+1行,输出的结果按保留原行顺序。
",:"可加可不加
后两种情况输出的都是二维数组
取列
取单列
a[:,n]
输出一维数组
取连续多列
a[:,n:m]
取不连续多列
a[:,[n,m,l]]
这样就提取了第n+1列,第m+1列,第l+1列,输出的结果按保留原行顺序。
":,"一定要加,不然变成取行
同样,后两种情况输出的都是二维数组
同取行和列
以提取第4行到第6行和第3列到第5列的交叉点为例:
print(a[[3,4,5],[2,3,4]])
或
print(a[3:5,2:4])
第一种方法还可以用于同取不相邻的行和列,及单个交叉点(直接输出单个数)
可见在同取时,交叉处用’‘,’'即可
使用条件判断取数(布尔索引)
print(a[a>10])
这样就输出了符合条件的数形成的一维数组
修改数值(包括索引)
本质是重新赋值
如果只是赋值
a[:,2:4]=0
print(a)
这样输出的a中的第3列到第5列都变成了0
如果使用判断
print(a<10)
那就会使条件成立的输出True,不成立的输出False
如果结合两者
a[a<10]=3
print(a)
这样满足条件的会输出3,不满足条件的输出原值
使用三元运算符赋值
np.where(a<10,0,10)
print(a)
结果中满足小于10的输出0,不满足的输出10
裁剪
a.clip(m,n)
print(a)
会把不大于m的数都换成m以输出,不小于n的换成n以输出
拼接数组
以下的a,b为任意行相等的二维数组
水平拼接
np.hstack((a,b))
竖直拼接
np.vstack((a,b))
数组的复制
复制后数组同步
b=a[:]
复制后数组不同步
b=a.copy()
numpy常用统计函数
函数 | 作用 |
---|---|
np.mean(a,axis=n) | 取均值 |
np.median(a,axis=n) | 取中值 |
np.min(a,axis=n) | 取最小值 |
np.max(a,axis=n) | 取最大值 |
np.ptp(a,axis=n) | 取极差 |
np.sum(a,axis=n) | 求和 |
np.std(a,axis=n) | 取标准差 |
nan和inf
nan表示not a number,是非数的意思
inf表示infinity,是无穷的意思
二者都是float型
nan的性质
nan != nan
nan进行运算的结果都是nan\
nan的判断
np.isnan(a)
这样原数组的nan都变成True,其他的变成False
而
a[np.isnan]
就选择了a中所有的nan
其他操作
获取最值位置
取最大值位置:
np.argmax(a,axis=n)
取最小值位置:
np.argmin(a,axis=n)
计算非零数的个数:
np.count_nonzero()