NumPy库是用于科学计算的一个开源Python扩充程序库,是其他数据分析包的基础包,它为Python提供了高性能数组与矩阵运算处理能力。
2.1 ndarray多维数组 NumPy库为Python带来了真正的ndarray多维数组功能。ndarray对象是一个快速而灵活的数据集容器 2.1.1 创建ndarray数组 NumPy库能将序列数据(列表、元组、数组或其他序列类型)转换为ndarray数组 import numpy as np
data1 = [5,7,9,20] #列表 arr1 = np.array(data1) arr1
array([ 5, 7, 9, 20])
data2 = (5,7,9,20) #元组 arr2 = np.array(data2) arr2
array([ 5, 7, 9, 20])
data3 = [[1,2,3,4],[5,6,7,8]] #对于多维数组的创建,使用嵌套序列数据即可完成 arr3 = np.array(data3) arr3
array([[1, 2, 3, 4], [5, 6, 7, 8]])
arr3.shape #shape是ndarray维度大小的元组
(2, 4)
arr3.dtype #dtype是解释说明ndarray数据类型的对象
dtype('int32')
data4 = [1,2,2,3.45,5] #当序列中有整数和浮点数时,NumPy会把数组的dtype定义为浮点数据类型 arr4 = np.array(data4) arr4
array([1. , 2. , 2. , 3.45, 5. ])
arr4.dtype
dtype('float64')
特殊数组 np.zeros(8) #zeros函数可以创建指定长度或形状的全0数组
array([0., 0., 0., 0., 0., 0., 0., 0.])
np.ones(4) #ones函数可以创建指定长度或形状的全1数组
array([1., 1., 1., 1.])
np.ones((4,6)) # ones函数可以创建指定长度或形状的全1数组
array([[1., 1., 1., 1., 1., 1.], [1., 1., 1., 1., 1., 1.], [1., 1., 1., 1., 1., 1.], [1., 1., 1., 1., 1., 1.]])
np.empty((2,3,2)) #mpty函数可以创建一个没有具体值的数组(即垃圾值)
array([[[9.42595773e-312, 2.81617418e-322], [0.00000000e+000, 0.00000000e+000], [6.23060065e-307, 2.42336543e-057]],
[[7.11697381e-091, 2.03997512e+184], [1.53389691e-052, 4.74680389e+174], [6.48224660e+170, 4.93432906e+257]]])
np.arange(10) #arange函数类似于Python的内置函数range,但是arange函数主要用于创建数组
array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
arr3
array([[1, 2, 3, 4], [5, 6, 7, 8]])
arr5 = np.ones_like(arr3) #ones_like函数可以根据传入的数组形状和dtype创建全1数组。 arr5
array([[1, 1, 1, 1], [1, 1, 1, 1]])
arr5.dtype
dtype('int32')
2.1.2 ndarray对象属性 data = [[2,4,5],[3,5,7]] arr = np.array(data) arr
array([[2, 4, 5], [3, 5, 7]])
arr.ndim #数据轴的个数
2
arr.size #元组的总个数
6
arr.itemsize #每个元素的字节大小 #arr数组的数据类型是int32位的, #对于计算机而言,1个字节是8位,所以arr的itemsize属性值为4。
4
arr.dtype #数据类型
dtype('int32')
2.1.3 ndarray数据类型 数组的数据类型有很多,读者只需要记住最常见的几种数据类型即可,如浮点数(float)、整数(int)、复数(complex)、布尔值(bool)、字符串(string_)和Python对象(object)。 arr1 = np.arange(6) arr1
array([0, 1, 2, 3, 4, 5])
arr1.dtype
dtype('int32')
arr2 = arr1.astype(np.float64) arr2
array([0., 1., 2., 3., 4., 5.])
arr2.dtype
dtype('float64')
arr3 = arr1.astype("string_") #对于创建好的ndarray,可通过astype方法进行数据类型的转换 arr3
array([b'0', b'1', b'2', b'3', b'4', b'5'], dtype='|S11')
arr3.dtype
dtype('S11')
arr3
array([b'0', b'1', b'2', b'3', b'4', b'5'], dtype='|S11')
arr3.astype(np.int32) #如果数组是字符串类型且全是数字的话,也可以通过astype方法将其转换为数值类型
array([0, 1, 2, 3, 4, 5])
arr = np.array(['2','hello']) arr
array(['2', 'hello'], dtype='<U5')
arr.astype("int32") #但如果字符串中有字符时,转换时就会报错,如图2.15所示。
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
~\AppData\Local\Temp/ipykernel_30528/2154082202.py in <module> ----> 1 arr.astype("int32") #但如果字符串中有字符时,转换时就会报错,如图2.15所示。
ValueError: invalid literal for int() with base 10: 'hello'
arr1 = np.arange(10) arr1.dtype
dtype('int32')
arr2 = np.ones(5) arr2.dtype
dtype('float64')
arr3= arr1.astype(arr2.dtype) #astype方法也可以通过另外一个数组的dtype进行转换 arr3.dtype
dtype('float64')
arr = np.arange(3) arr.dtype
dtype('int32')
arr.astype("float64") #astype方法会创建一个新的数组,并不会改变原有数组的数据类型
array([0., 1., 2.])
arr
array([0, 1, 2])
2.1.4 数组变换 1.数组重塑 arr = np.arange(9) arr
array([0, 1, 2, 3, 4, 5, 6, 7, 8])
arr.reshape((3,3)) #对于定义好的数组,可以通过reshape方法改变其数据维度。传入的参数为新维度的元组,
array([[0, 1, 2], [3, 4, 5], [6, 7, 8]])
arr = np.array([[3,4,5],[1,2,3]]) arr.reshape((3,2)) #多维数组也可以被重塑
array([[3, 4], [5, 1], [2, 3]])
arr = np.arange(12) arr.reshape((3,-1)) #reshape的参数中的一维参数可以设置为-1,表示数组的维度可以通过数据本身来推断
array([[ 0, 1, 2, 3], [ 4, 5, 6, 7], [ 8, 9, 10, 11]])
arr = np.arange(10).reshape((5,2)) arr
array([[0, 1], [2, 3], [4, 5], [6, 7], [8, 9]])
arr.ravel() #与reshape相反的方法是数据散开(ravel)数据或扁平化(flatten)
array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
arr.flatten()
array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
arr #数据重塑不会改变原数组。
array([[0, 1], [2, 3], [4, 5], [6, 7], [8, 9]])
2.数组合并 arr1 = np.arange(12).reshape((3,-1)) arr1
array([[ 0, 1, 2, 3], [ 4, 5, 6, 7], [ 8, 9, 10, 11]])
arr2 = np.arange(12,24).reshape((3,4)) arr2
array([[12, 13, 14, 15], [16, 17, 18, 19], [20, 21, 22, 23]])
np.concatenate([arr1,arr2],axis = 0) #数组合并用于几个数组间的操作,concatenate方法通过指定轴方向,将多个数组合并在一起
array([[ 0, 1, 2, 3], [ 4, 5, 6, 7], [ 8, 9, 10, 11], [12, 13, 14, 15], [16, 17, 18, 19], [20, 21, 22, 23]])
np.concatenate([arr1,arr2],axis = 1)
array([[ 0, 1, 2, 3, 12, 13, 14, 15], [ 4, 5, 6, 7, 16, 17, 18, 19], [ 8, 9, 10, 11, 20, 21, 22, 23]])
np.vstack((arr1,arr2)) #NumPy中提供了几个比较简单易懂的方法,也可以进行数组合并,如vstack和hstack
array([[ 0, 1, 2, 3], [ 4, 5, 6, 7], [ 8, 9, 10, 11], [12, 13, 14, 15], [16, 17, 18, 19], [20, 21, 22, 23]])
np.hstack((arr1,arr2))
array([[ 0, 1, 2, 3, 12, 13, 14, 15], [ 4, 5, 6, 7, 16, 17, 18, 19], [ 8, 9, 10, 11, 20, 21, 22, 23]])
3.数组拆分 arr = np.arange(12).reshape((6,2)) arr
array([[ 0, 1], [ 2, 3], [ 4, 5], [ 6, 7], [ 8, 9], [10, 11]])
np.split(arr,[2,4]) #数组拆分是数组合并的相反操作,通过split方法可以将数组拆分为多个数组
[array([[0, 1], [2, 3]]), array([[4, 5], [6, 7]]), array([[ 8, 9], [10, 11]])]
4.数组转置和轴对换 arr = np.arange(12).reshape(3,4) arr
array([[ 0, 1, 2, 3], [ 4, 5, 6, 7], [ 8, 9, 10, 11]])
arr.transpose((1,0)) #转置是数组重塑的一种特殊形式,可以通过transpose方法进行转置 #transpose方法需要传入轴编号组成的元组,这样就完成了数组的转置
array([[ 0, 4, 8], [ 1, 5, 9], [ 2, 6, 10], [ 3, 7, 11]])
arr.T #除了使用transpose方法外,数组有着T属性,可用于数组的转置
array([[ 0, 4, 8], [ 1, 5, 9], [ 2, 6, 10], [ 3, 7, 11]])
arr = np.arange(16).reshape((2,2,4)) arr
array([[[ 0, 1, 2, 3], [ 4, 5, 6, 7]],
[[ 8, 9, 10, 11], [12, 13, 14, 15]]])
arr.swapaxes(1,2) #ndarray的swapaxes方法用于轴对换
array([[[ 0, 4], [ 1, 5], [ 2, 6], [ 3, 7]],
[[ 8, 12], [ 9, 13], [10, 14], [11, 15]]])
2.1.5 NumPy的随机数函数 arr = np.random.randint(100,200,size=(5,4)) #可以通过randint函数生成整数随机数 arr
array([[148, 112, 119, 144], [194, 123, 131, 172], [147, 104, 168, 165], [101, 116, 131, 195], [160, 149, 194, 173]])
arr = np.random.randn(2,3,5) #如randn函数,例如,生成平均数为0,标准差为1的正态分布的随机数 arr
array([[[-0.48274113, 0.07529806, -1.81740745, 1.286357 , -2.55607301], [ 1.07998934, -0.31404883, -2.297629 , -0.66385757, 0.95792075], [-0.51302191, -2.53759601, -0.26012523, 0.71636383, 2.57003766]],
[[ 1.9540761 , 1.07840586, -0.24478286, 0.8714337 , 0.70059484], [-0.14210736, 0.09356213, -2.96823017, -0.55159717, -1.63454057], [-0.31135985, -1.52214541, 1.18820464, 1.96057804, -0.59961429]]])
arr = np.random.normal(4,5,size=(3,5)) #通过normal函数生成指定均值和标准差的正态分布的数组 arr
array([[ 1.03057369e+01, 2.59867561e-01, 1.43530708e+01, 5.99577642e+00, 1.41228837e-01], [-1.56586338e+00, 1.99540963e+00, 7.90100440e+00, 1.64716969e+00, -7.06954944e+00], [ 4.79296269e+00, 5.51927601e-03, 7.69985462e+00, -8.28181420e+00, 7.95558205e+00]])
arr = np.random.randint(100,200,size=(5,4)) arr
array([[107, 142, 175, 160], [122, 124, 178, 193], [149, 123, 198, 100], [170, 165, 165, 139], [116, 151, 111, 189]])
np.random.permutation(arr) #对一个序列随机排序,不改变原数组
array([[170, 165, 165, 139], [116, 151, 111, 189], [149, 123, 198, 100], [122, 124, 178, 193], [107, 142, 175, 160]])
arr
array([[107, 142, 175, 160], [122, 124, 178, 193], [149, 123, 198, 100], [170, 165, 165, 139], [116, 151, 111, 189]])
np.random.shuffle(arr) #对一个序列随机排序,改变原数组 arr
array([[170, 165, 165, 139], [122, 124, 178, 193], [107, 142, 175, 160], [149, 123, 198, 100], [116, 151, 111, 189]])
2.2 数组的索引和切片 2.2.1 数组的索引 import numpy as np
arr = np.arange(10) arr
array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
arr[3] #一维数组的索引类似Python列表
3
arr[-1]
9
arr[2] = 123 arr
array([ 0, 1, 123, 3, 4, 5, 6, 7, 8, 9])
arr = np.arange(15).reshape(3,5) arr
array([[ 0, 1, 2, 3, 4], [ 5, 6, 7, 8, 9], [10, 11, 12, 13, 14]])
arr[0] # 对于二维数组,可在单个或多个轴向上完成切片
array([0, 1, 2, 3, 4])
arr[2]
array([10, 11, 12, 13, 14])
arr[0][3] #如果需要获取各个元素
3
2.2.2 数组的切片 arr = np.arange(6) arr
array([0, 1, 2, 3, 4, 5])
arr[2:5]
array([2, 3, 4])
arr = np.arange(12).reshape(4,3) arr
array([[ 0, 1, 2], [ 3, 4, 5], [ 6, 7, 8], [ 9, 10, 11]])
arr[2:] #当在中括号中输入一个参数时,数组就会按照0轴(也就是第一轴)方向进行切片
array([[ 6, 7, 8], [ 9, 10, 11]])
arr
array([[ 0, 1, 2], [ 3, 4, 5], [ 6, 7, 8], [ 9, 10, 11]])
arr[:,1] # 通过传入多个参数(可以是整数索引和切片),即可完成任意数据的获取 # 只有使用冒号才会选取整个轴。
array([ 1, 4, 7, 10])
arr[:,1:2]
array([[ 1], [ 4], [ 7], [10]])
arr[2:,1:]
array([[ 7, 8], [10, 11]])
2.3 数组的运算 2.3.1 数组和标量间的运算 arr = np.array([1,2,3]) arr*10
array([10, 20, 30])
arr*arr
array([1, 4, 9])
arr-arr
array([0, 0, 0])
arr = np.random.randn(3,3) arr
array([[-1.10434004, -0.38970982, 0.68926712], [-1.11139007, -0.60620091, -0.43321889], [-0.18284226, 1.65765572, -0.79486849]])
np.abs(arr) # 通过abs函数求绝对值
array([[1.10434004, 0.38970982, 0.68926712], [1.11139007, 0.60620091, 0.43321889], [0.18284226, 1.65765572, 0.79486849]])
np.square(arr) #square函数求平方
array([[1.21956692, 0.15187374, 0.47508917], [1.23518789, 0.36747954, 0.1876786 ], [0.03343129, 2.74782248, 0.63181591]])
arr1 = np.random.randint(1,10,size=(5)) arr1
array([9, 1, 8, 2, 3])
arr2 = np.random.randint(1,10,size = (5)) arr2
array([8, 8, 8, 1, 8])
np.add(arr1,arr2) #add函数用于两个数组的相加
array([17, 9, 16, 3, 11])
np.minimum(arr1,arr2) #minimum函数可以计算元素最小值
array([8, 1, 8, 1, 3])
arr = np.random.normal(2,4,size = (6)) arr
array([ 5.06802817, -1.26210681, -2.55346754, -5.70727512, 3.25494685, 5.86244808])
np.modf(arr) # 有些通用函数还可以返回两个数组,例如modf函数,可以返回数组元素的小数和整数部分
(array([ 0.06802817, -0.26210681, -0.55346754, -0.70727512, 0.25494685, 0.86244808]), array([ 5., -1., -2., -5., 3., 5.]))
2.3.3 条件逻辑运算 arr1 = np.array([1,2,3,4]) arr2 = np.array([5,6,7,8]) cond = np.array([True,False,False,True]) result = np.where(cond,arr1,arr2) result
#如果需要通过cond的值来选取arr1和arr2的值, #当cond为True时,选择arr1的值,否则选择arr2的值
array([1, 6, 7, 4])
arr = np.random.randn(4,4) arr
array([[-0.09650043, 0.31929566, 0.67190973, -0.951201 ], [ 1.10148109, 0.91289976, 1.24039204, -2.09494457], [-1.47448762, -1.61059505, -0.02424096, -1.00035527], [-1.71134107, -0.73639959, -0.63883441, 0.67764956]])
new_arr = np.where(arr>0,1,-1) new_arr
array([[-1, 1, 1, -1], [ 1, 1, 1, -1], [-1, -1, -1, -1], [-1, -1, -1, 1]])
2.3.4 统计运算 arr = np.random.randn(4,4) arr
array([[-0.33407573, 1.89601251, -0.25068698, 1.09899693], [-0.7436235 , 0.96724716, 2.51586733, 0.78559764], [-0.61260085, -0.1447176 , 0.75132781, 0.91617282], [-0.33995589, -1.61785421, -0.12434649, 1.02720805]])
arr.sum()
5.790568998522431
arr.mean()
0.36191056240765196
arr.std() #std函数用于求标准差
1.0283623213025257
arr
array([[-0.33407573, 1.89601251, -0.25068698, 1.09899693], [-0.7436235 , 0.96724716, 2.51586733, 0.78559764], [-0.61260085, -0.1447176 , 0.75132781, 0.91617282], [-0.33995589, -1.61785421, -0.12434649, 1.02720805]])
arr.mean(axis = 1) #用于计算指定轴方向的统计值
array([ 0.60256168, 0.88127216, 0.22754555, -0.26373714])
arr.sum(0)
array([-2.03025597, 1.10068786, 2.89216167, 3.82797544])
arr = np.arange(9).reshape(3,3) arr
array([[0, 1, 2], [3, 4, 5], [6, 7, 8]])
arr.cumsum(0) #所有元素的累积和
array([[ 0, 1, 2], [ 3, 5, 7], [ 9, 12, 15]], dtype=int32)
arr.cumprod(1) #所有元素的累积积
array([[ 0, 0, 0], [ 3, 12, 60], [ 6, 42, 336]], dtype=int32)
2.3.5 布尔型数组运算 arr = np.random.randn(20) arr
array([-0.20661816, 0.10874043, -0.40256083, -0.19071145, -1.26373101, 1.56890466, -1.01231556, -0.18248971, 1.23433954, -0.64327127, -1.64106717, -1.20622075, 0.96636457, -0.13955697, 1.31806702, -1.18310487, 0.02948617, -2.16793703, 0.88963934, 1.01751536])
arr = np.array([True,False,False,True]) arr
array([ True, False, False, True])
arr.any() #any方法用于测试数组中是否存在一个或多个True
True
arr.all() #all方法用于检查数组中的所有值是否为True
False
2.3.6 排序 arr = np.random.randn(10) arr
array([-2.08464944, 1.79606612, 0.88671682, -1.5369521 , -1.46048203, 1.18515803, 2.20130482, -0.32108926, -0.7320761 , 0.12610864])
arr.sort() arr
array([-2.08464944, -1.5369521 , -1.46048203, -0.7320761 , -0.32108926, 0.12610864, 0.88671682, 1.18515803, 1.79606612, 2.20130482])
arr = np.random.randn(5,3) arr
array([[-0.90307983, -0.54527699, 0.5234602 ], [ 0.01153178, -0.87114807, -0.07794886], [-0.34698081, -0.07907388, 0.60341693], [-0.06539896, -0.34155509, 1.37263374], [-0.5427262 , -0.09412761, 1.20774627]])
arr.sort(1) #对于多维数组,可以通过指定轴方向进行排 arr
array([[-0.90307983, -0.54527699, 0.5234602 ], [-0.87114807, -0.07794886, 0.01153178], [-0.34698081, -0.07907388, 0.60341693], [-0.34155509, -0.06539896, 1.37263374], [-0.5427262 , -0.09412761, 1.20774627]])
2.4 数组的存取 arr = np.arange(12).reshape(3,4) arr
array([[ 0, 1, 2, 3], [ 4, 5, 6, 7], [ 8, 9, 10, 11]])
np.savetxt("che1ex1.csv",arr,fmt="%d",delimiter=",")
arr = np.loadtxt("che1ex1.csv",delimiter=",") arr
array([[ 0., 1., 2., 3.], [ 4., 5., 6., 7.], [ 8., 9., 10., 11.]])
from PIL import Image
im = np.array(Image.open("C:/Users/itcast/Desktop/image/1.jpg")) print(im.shape,im.dtype)
(598, 601, 3) uint8
im #通过图中的代码可以看出,图像转换成三维数组后,维度分别为宽度、长度和RGB值。
array([[[128, 129, 131], [ 16, 4, 0], [246, 208, 61], ..., [255, 209, 10], [243, 208, 56], [ 11, 4, 0]],
[[129, 130, 132], [ 14, 2, 0], [246, 208, 61], ..., [255, 209, 10], [243, 208, 56], [ 12, 5, 0]],
[[123, 124, 126], [ 20, 8, 0], [246, 208, 61], ..., [255, 209, 10], [243, 208, 56], [ 11, 4, 0]],
...,
[[139, 139, 137], [251, 243, 197], [248, 221, 90], ..., [255, 219, 51], [248, 217, 90], [ 8, 5, 0]],
[[120, 120, 118], [255, 255, 212], [243, 216, 85], ..., [255, 219, 51], [248, 217, 90], [255, 255, 216]],
[[116, 116, 114], [255, 255, 212], [237, 210, 79], ..., [255, 220, 52], [249, 218, 91], [255, 255, 218]]], dtype=uint8)
b = [200,200,200] -im new_im = Image.fromarray(b.astype("uint8")) new_im.save('C:/Users/itcast/Desktop/image/3.jpg')
|