导入numpy包:
import numpy as np
一.数组基础
1.1数据类型
(1)整型数组和浮点型数组
列表有个缺点,即其中可以容纳不同的数据类型,numpy数组则克服了这个缺点,以达到节约内存的目的
import numpy as np
# 创建整型数组
arr1 = np.array([1, 2, 3])
# 创建浮点型数组
arr2 = np.array([1.0, 2, 3])
print(f'{arr1}\n{arr2}')
用print输出后,元素之间没有逗号,好处就是可以和python的列表分开,也可以避免小数点和逗号之间的混淆
(2)同化定理
往浮点数组里插入整数,该整数会被自动升级为浮点数
往整型数组里插入浮点数,该浮点数会被自动截断为整数(不四舍五入)
好理解,不做代码示例
(3)共同改变定理
想将一个整型数组转换成浮点型数组,就需要共同改变
规范的方法是用到.astype()方法
import numpy as np
# 创建整型数组
arr1 = np.array([1, 2, 3])
# 转换成浮点型数组
arr2 = arr1.astype(float)
print(f'{arr1}\n{arr2}')
结果与上面一致
除了用到方法外,再运算过程中,整型数组往往会不经意间升级成浮点型数组,但是浮点型数组一般比较难降级
import numpy as np
# 创建整型数组
arr1 = np.array([1, 2, 3])
# 运算中升级成浮点型数组
print(arr1+0.0)
print(arr1*1.0)
print(arr1/1) # 整型数组作除法运算都会转换成浮点型(即便是除以整数)
arr2 = np.array([1.0, 2.0, 3.0])
print(arr1+arr2)
以上的方法都可在运算中将整型数组升级为浮点型数组
1.2数组维度
(1)一维数组和二维数组
不同维度之间从外形上的区别:
n维数组用n个中括号表示
不同维度数组的形状参数:
一维数组的形状参数形如:x或(x,)
二维数组的形状参数形如:(x,y)
三维数组的形状参数形如:(x,y,z)
可以用np.ones()函数造数组,后面有讲到
import numpy as np
# 造1 2 3维数组
arr1 = np.ones(3)
arr2 = np.ones((1, 3))
arr3 = np.ones((1, 1, 3))
print(arr1)
print(arr2)
print(arr3)
可以用.shape方法查看形状
import numpy as np
# 造1 2 3维数组
arr1 = np.ones(3)
arr2 = np.ones((1, 3))
arr3 = np.ones((1, 1, 3))
print(arr1.shape)
print(arr2.shape)
print(arr3.shape)
(2)不同维度数组的转换
不同维度的数组再很多时候不能在同一个函数出现,所以需要转换数组的维度
可以使用.reshape的方法,该方法需要传入重塑后的形状(shape)参数
神奇的是,给定了其他维度的数值,剩下一个维度可以填-1,它可以自己计算
如下演示一维数组升级为二维数组:
import numpy as np
arr1 = np.arange(10)
arr2 = arr1.reshape((2, -1))
print(arr1)
print(arr2)
如下演示将二维数组降为一维数组:
import numpy as np
arr1 = np.arange(10).reshape(2, -1)
arr2 = arr1.reshape(-1)
print(arr1)
print(arr2)
形状参数中的-1,表示让它自己算,但是不能出现多个-1
可以将一维数组称为向量,二维数组称为矩阵
二.数组的创建
2.1创建指定数组
当知道数组中的每一个元素时,可以使用np.array()函数,将python列表转换为numpy数组
如下为代码示例:
import numpy as np
# 创建一维数组——向量
arr1 = np.array([1, 2, 3])
# 创建二维数组——行矩阵
arr2 = np.array([[1, 2, 3]])
# 创建二维数组——列矩阵
arr3 = np.array([[1], [2], [3]])
# 创建二维数组——矩阵
arr4 = np.array([[1, 2, 3], [4, 5, 6]])
print(arr1)
print(arr2)
print(arr3)
print(arr4)
2.2创建递增数组
递增数组用np.arange()函数创建(arange的全称是array_range)
import numpy as np
# 创建一个从0到10(不包括)的递增数组
arr1 = np.arange(10)
print(arr1)
# 创建一个从10到20(不包括)的递增数组
arr2 = np.arange(10, 20)
print(arr2)
# 创建一个从10到20(不包括),步长为2的递增数组
arr3 = np.arange(10, 20, 2)
print(arr3)
2.3创建同值数组
可以用np.zeros()以及np.ones()函数创建同值数组
import numpy as np
# 创建形状为3同0数组
arr1 = np.zeros(3)
print(arr1)
# 创建形状为(1, 3)同1数组
arr2 = np.ones((1, 3))
print(arr2)
# 创建形状为(2, 3)同3.14数组
arr3 = 3.14*np.ones((2, 3))
print(arr3)
可以注意到输出的是浮点型数组,可能是因为避免被插进去的浮点数被折断
2.4创建随机数组
可以使用np.random系列函数
import numpy as np
# 创建0-1均匀分布的浮点型随机数组
arr1 = np.random.random(5) # 形状为5的向量
print(arr1)
# 创建60-100范围内均匀分布的三行三列随机数组
arr2 = 40*np.random.random((3, 3)) + 60 # 前面代表区间为(0, 40),后面代表区间加60
print(arr2)
# 创建随机整型数组
arr3 = np.random.randint(10, 100, (2, 3))
print(arr3)
# 服从正态分布的随机数组
arr4 = np.random.normal(0, 1, (2, 3)) # 第一个位置参数是均值,第二个是标准差,第三个是形状
print(arr4)
# 当为0-1正态分布时,这种情况可以直接换为
arr5 = np.random.randn(2, 3)
print(arr5)
三.数组的索引
3.1访问数组元素
与列表一致,访问时使用中括号,索引从0开始
(1)访问向量
import numpy as np
arr1 = np.arange(1, 10)
# 可以正向访问,也可以反向访问
print(arr1[3])
print(arr1[-1])
# 修改数组元素
arr1[5] = 100
print(arr1)
(2)访问矩阵
import numpy as np
arr1 = np.array([[1, 2, 3], [4, 5, 6]])
# 访问元素
print(arr1[0, 2])
print(arr1[1, -2])
# 修改元素
arr1[1,-1] = 100
print(arr1)
3.2花式索引
与原索引不同,有两层中括号
(1)向量的花式索引
import numpy as np
arr1 = np.arange(0, 90, 10)
print(arr1[[0, 2]])
(2)矩阵的花式索引
表现形式为[[行], [列]]
import numpy as np
arr2 = np.arange(1, 17).reshape(4, 4)
print(arr2)
print(arr2[[0, 1, 2], [1, 1, 1]])
print(arr2[[0, 1, 2], [2, 1, 0]])
从以上实例可以看出,花式索引也就是用向量替代普通索引的行列元素,且花式索引输出的任然是一个向量
3.3访问数组切片
(1)向量的切片
和python中序列切片一样
import numpy as np
arr2 = np.arange(1, 10)
print(arr2[1: -1])
print(arr2[1: 6])
print(arr2[1: -1: 2])
可以有两种理解,一是切出来从a到b(不包括)的数组,二是去掉a前和b(包括)后的数组
(2)矩阵的切片
可以理解为从一个矩阵中切出另一个矩阵
import numpy as np
arr2 = np.arange(1, 17).reshape(4, 4)
print(arr2)
print(arr2[1: 3, 1: -1])
# 跳跃切片
print(arr2[::2, ::2])
print(arr2[::3, ::3])
(3)提取矩阵的行
import numpy as np
arr2 = np.arange(1, 17).reshape(4, 4)
print(arr2[2, :])
print(arr2[2]) # 提取行的时候可以简写,但是提取列不行
print(arr2[1: 3, :])
(4)提取矩阵的列
import numpy as np
arr2 = np.arange(1, 17).reshape(4, 4)
print(arr2[:, 2])
print(arr2[:, 1: 3])
当提取单独一行列的时候,输出的是向量,为了节省空间,列矩阵更消耗空间,因为列矩阵有两层中括号
如果想把向量转换成列矩阵也有办法
import numpy as np
arr2 = np.arange(1, 17).reshape(4, 4)
arr3 = arr2[:, 2].reshape((1, -1))
print(arr3.T) # 转置操作,.T只对矩阵生效
3.4数组切片仅视图
(1)数组切片仅视图
换言之,numpy数组并不会创建新的变量,对其切片进行修改也是对原数组的修改
import numpy as np
arr1 = np.arange(1, 10)
print(arr1)
cut = arr1[:3]
cut[0] = 100
print(cut)
print(arr1)
这个设定是极好的,因为不用创建新的变量,可以大大节省内存
(2)备份切片为新变量
如果真的需要,可以用.copy()的方法
cut = arr1[:3].copy()
对其修改不会影响原数组
3.5数组赋值仅是绑定
(1)数组赋值仅是绑定
和切片一样,数组之间的赋值不会创建新变量,只是将它们绑定在一起
import numpy as np
arr1 = np.arange(1, 10)
arr2 = arr1
print(arr1)
arr2[0] = 100
print(arr1)
print(arr2)
(2)复制数组为新变量
跟前面一样,用.copy()方法,可以将他们进行独立