文章目录

NumPyNumPy介绍导入NumPyNumPy数组序列生成数组函数生成数组range,arange,linspace

其他常用函数

N维数组的属性NumPy数组的运算向量运算算数运算逐元素运算、点乘运算

操作数组元素索引访问数组切片访问数组转置与展平

NumPy的广播NumPy的高级索引整数索引布尔索引

数组的堆叠水平方向堆叠竖直方向堆叠深度方向堆叠行堆叠和列堆叠

数组的分割随机数

NumPy

NumPy介绍

在Python中有列表和数组模块,但是都不好用,列表的缺点是要保存每个对象的指针,如果你的列表有一百万个元素,他就有一百万个指针,而数组又只支持一维数组,并不适合数值运算

NumPy的模块支持数组和矩阵(向量)的运算,对机器学习算法比较友好,支持n维数组,有强大的数学运算对很多第三方库(SciPy,Pandas)都提供的底层支持

导入NumPy

首先要确保你的安装了NumPy库

pip install numpy

一般我们会给NumPy起别名为np

NumPy数组

序列生成数组

生成数组最简单的方法就是用array()方法,他可以接收任意类型的数据(列表、元组等)作为数据源

需要注意的是,如果各种数据的数据类型不统一,但是数据类型可以相互转换,就会进行自动转换,浮点数和整数都存在时,就会将整数自动转化成浮点数

每一个数组都可以利用dtype数据(ArrName.dtype)来输出数组中数据的类型,如果没有显示指定(ArrName.astype()),数组就会自动推断数据类型

例如

import numpy as np

print(np.__version__)

list1 = [1, 2, 2.5, 3, 4, 5]

arr1 = np.array(list1)

print(arr1.dtype)

arr1 = arr1.astype(int)

print(arr1.dtype)

如果数据序列是嵌套的,而且嵌套序列是等长的,就会自动转换为高维数组,例如列表中有两个分别带有4个元素的子列表,数组就会自动变为两行四列的二维数组

函数生成数组

我们可以用arange()方法来生成数组,参数如下

arange(start, stop, step, dtype)

start与stop为起止位置,step为步长,区间为左闭右开,例如

arr3 = np.arange(1, 10, 2, int)

print(arr3)

对于数组的操作有一个是

arr3 = arr3 + 1

需要注意的是这个操作是给所有元素加1,但是这个1实际上是利用了“广播机制”,将1扩展为等长的数组,才能进行相加

range,arange,linspace

这里是三个函数,第一个是我们之前学习到的range,他的返回值本质上是一个可迭代对象,可以看作是一个迭代器,而且也有一定的局限性,例如步长只能是整数

第二个是用于创建数组的方法,步长可以是浮点数,而且他的底层其实是C语言,因此执行效率也会比较高,对于arange他的返回值就是数组对象本身了

第三个是也是用于创建数组的方法,他的好处是避免了每一次创建数组都要手动算一下步长,他的参数有三个,起始位置,停止位置,数据个数,例如

arr4 = np.linspace(1,10,20)

其他常用函数

方法说明示例zeros生成全零数组ze = zeros((2,3)) 生成两行三列0数组ones生成全一数组与上面一样shape参数描述轮廓one = np.ones(shape = [3, 4], dtype = float)zeros_like结构和某数组一样的全零数组ze1 = zeros_like(ze)ones_like结构和某数组一样的全一数组one = zeros_like(one)

其余函数还有,empty_like、full_like,等等

N维数组的属性

我们首先要知道,内存的本质还是一维的,用狭隘的眼光来看他甚至只能从一个方向存储删除数据,因此我们所说的n维数组实际上是一个逻辑的结构,并非内存的真实结构

一个n维数组的本质就是用n个同类的数据容器来存储数据

我们可以用ndim输出数组的维度

arr1 = np.arange(1,10)

print(arr1.ndim)

同样的,我们也可以用shape查看数组的形状信息

print(arr1.shape)

我们也可以用reshape()方法来改变一维数组的形状信息,也就是重构或者说变形

arr1 = np.arange(1,10)

print(arr1.shape)

print(arr1)

arr2 = arr1.reshape(3,3)

print(arr2.shape)

print(arr2)

需要注意的是,三位数组的形状信息是分别对应着宽、高、长

NumPy数组的运算

向量运算

如果我们想求两个列表元素对应的和,我们可以使用for循环,列表推导式,也可以将他们转换为数组直接求和即可

import numpy as np

arr1 = np.arange(1,11)

arr2 = np.arange(11,21)

arr3 = arr1 + arr2

print(arr1)

print(arr2)

print(arr3)

算数运算

NumPy有着强大的算数运算函数,只需要直接调用即可

如果要进行普通的数学运算,直接跟两个数字直接运算的方法一模一样,支持加减乘除取余乘方

注意,要操作数组的形状一致,除数不要为0就行

还有许多统计函数,例如

函数说明sum求和min最小值max最大值median中位数mean平均数average加权平均数std标准差var方差

逐元素运算、点乘运算

N维数组实际上类似于矩阵,一般来说,加减乘除是元素对元素的运算

这里的乘法与矩阵乘法或是向量乘法不同,而是元素对元素的乘法

对于数学中的点乘操作NumPy也有对应的方法为dot(),也可以使用@符号替换乘法操作,意为点乘

例如

arr1 = np.arange(1, 10)

arr2 = np.arange(11, 20)

arr1 = arr1.reshape(3, 3)

arr2 = arr2.reshape(3, 3)

print(arr1*arr2)

print(arr1@arr2)

print(np.dot(arr1,arr2))

后两种符合的就是矩阵乘法的操作了

其他矩阵运算的函数

方法说明a.I返回a的逆矩阵a.T返回a的转置矩阵a.A返回a对应的二维数组

操作数组元素

索引访问数组

索引是数组中元素所在的编号,类似于列表和C/C++中的数组,像一个指针一样对数组进行访问

一维数组二维数组的访问也是相同的,同样可以更改数组中的值

切片访问数组

与Python的列表一样,NumPy也可以使用切片访问和修改数据,我们可以批量获取符合要求的元素,提取出一个新的数组

例如

arr1 = np.arange(1,10)

sl = slice(2,9,2)

arr2 = arr1[sl]

print(arr2)

print(arr1)

这里的arr1表示原有数组,sl表示切片对象,是利用slice函数构造出来的,代表从2到9,步长为2,再对arr1切片得到arr2

也可以利用类似列表的切片方法arr2 = arr1[2:9:2]

转置与展平

我们可以通过transpose()方法将二维数组转置,也可以通过我们上面提到过的ArrName.T来进行转置

要将多维数组转化成一维数组,就要使用ravel()方法完成这个功能

例如

arr1 = np.arange(1,10)

arr1 = arr1.reshape(3,3)

print(arr1)

arr1 = arr1.T

print(arr1)

arr1 = arr1.ravel()

print(arr1)

flatten()函数也可以进行展平操作,不同的是,flatten会重新分配内存,进行一次深拷贝,但是原数组并没有改变

NumPy的广播

实际上就是对两个数组进行加减乘除运算时,即便两个数组形状不同,NumPy会自动填充小数组中的元素来匹配大数组,这种机制也叫做广播(broadcasting),这个过程中需要的性能比较小,也无须关注实现细节

NumPy的高级索引

整数索引

这种索引的使用场景是为了补充之前的直接索引和切片索引,一旦我们想要访问的数据没有规律可循,但数据量比较大的时候,我们可以自行指定一个索引表进行访问

例如

import numpy as np

arr1 = np.arange(1,50)

index = [5,23,23,32,37,16]

print(arr1[index])

如果是二维数组,只需要写一个二维索引表即可

需要注意的是,我们也可以只访问行索引和列索引,行索引直接传入一维列表即可,列索引需要用冒号隔开,在冒号之后传入一维列表即为列索引

布尔索引

这里就类似于筛选的功能,符合条件(True)的数据就会被保留下来,不符合则会被过滤

例如

arr1 = np.arange(1,50)

index = [5,23,23,32,37,16]

arr1 = arr1[index]

print(arr1[arr1<30])

需要注意的是这里的arr1<30实际上就是利用了之前的广播,将30扩展成一个同样形状的数组,然后分别进行比较

数组的堆叠

这里的堆叠可以将数组理解成书,他分为三中,水平方向堆叠,类比两本书横向堆叠放,垂直方向堆叠,就是两本书纵向堆叠,深度方向堆叠就是一本书摞在另一本书上了

水平方向堆叠

hstack()这里的h表示水平,stack表示堆叠,需要注意的是,这个函数的参数是一个元组,元组内的元素可以是列表,数组等,返回结果是一个数组

例如

list1 = [[1,1,2],[3,4,4]]

list2 = [[2,3,3],[4,4,5]]

arr1 = np.hstack((list1,list2))

print(arr1)

他是把两个元素的前两项叠在一起,后两项叠在一起,之后再组成一个数组

竖直方向堆叠

vstack() 例如

list1 = [[1,1,2],[3,4,4]]

list2 = [[2,3,3],[4,4,5]]

arr1 = np.vstack((list1,list2))

print(arr1)

深度方向堆叠

dstack() 例如

list1 = [[1,1,2],[3,4,4]]

list2 = [[2,3,3],[4,4,5]]

arr1 = np.dstack((list1,list2))

print(arr1)

这里输出的就是一个三维数组了,相当于把两片纸堆叠在一起就有了高度

要注意元素之间的对应关系

行堆叠和列堆叠

这里就好理解很多了,因为上面的三个操作是在三维空间里的堆叠,而这里只是针对二维的数据

行堆叠 column_stack()

列堆叠 row_stack()

数组的分割

分割就是与堆叠的你操作,那也就分为水平分割,垂直分割,深度分割

分别用hsplit(),vsplit(),dsplit()实现

随机数

NumPy中含有随机数模块,random

随机数其实是由随机数种子根据一定规则计算出的数值,因此只要计算方法和种子一定,随机数就是不会变了,如果不设置随机种子,就会根据系统时间生成随机种子

例如

import numpy as np

rdm = np.random.RandomState(1)

np.random.seed(20231214) # 定义随机种子

# 生成两行三列的随机数组,服从均匀分布

rand = np.random.rand(2,3)

print(rand)

# 生成两行三列的随机数组,服从标准正态分布

randn = np.random.randn(2,3)

print(randn)

# 生成两行三列的1到10的随机整数

randint = np.random.randint(1,10,(2,3))

print(randint)

感谢各位的支持,如果你发现文章中有任何不严谨或者需要补充的部分,欢迎在评论区指出

文章链接

评论可见,请评论后查看内容,谢谢!!!
 您阅读本篇文章共花了: