文章目录
- 一:简介
- 二:NumPy库组成介绍
- 1.NumPy的组成
- 2.NumPy优点
- 3.数据结构和数据类型的区别
- (1)数据类型
- (2)数据结构
- 4.NumPy数据类型
- 三:NumPy ndarray
- 1.简介
- (1)大型数组集合
- (2)多维
- (3)相同类型
- (4)类似标量操作语法
- 2.NumPy矩阵和数组区别
- 3.shape,dtype,ndim
- 4.生成ndarray
- (1)基础创建方法
- (2)其他方法
- 5.ndarray的数据类型
- 6.NumPy数组算术
- (1)向量化
- (2)相同尺寸数组算术操作
- (3)不同尺寸数组算术操作
- 7.ndarray数组索引与切片
- (1)基础索引切片以及与序列的不同
- (2)数组拷贝
- (3)多维数组拷贝
- (4)布尔索引
- (5)神奇索引
- 8.数组转置和换轴
- (1).T属性,适用于一,二维数组,如下:
- (2)transpose高维数组转置
- (3)swapaxes对换轴
- 四:通用函数
- 五:数组向量化的一些方法
- 1.条件逻辑
- 2.数组和统计方法
- 3.布尔值数组的方法
- 4.排序
- 5.一维数组基础集合操作
- 6.使用数组进行文件输入和输出
一:简介
NumPy系统,全称Numerical Python,是Python的一种开源的数值计算扩展工具(一种开源的科学计算库)。可用来存储和处理大型矩阵,比Python自身的嵌套列表要高效的多。
它是目前Python数值计算中最为重要的基础包,大多数其他数值计算包都提供了基于NumPy的科学函数功能,
将Numpy的数组对象作为数据交换的媒介
。
这里要向大家介绍包与库的区别
:其实,我们的每个python文件都是模块;库是一些有相似功能的模块的集合;包是对文件目录进行管理,里面既有模块,还有子目录,第一个模块是__init__模块。有时候库和包可以看成一样的。
说白了,NumPy库就是提供一个高效高级数组对象以及操作它的方法,其他科学计算库大多把这个高级数组对象进行进一步处理。
二:NumPy库组成介绍
1.NumPy的组成
(1)一个强大的N维数组对象Array
一个高级数据类型,提供了基于数组和矩阵的便捷算术操作以及灵活的广播函数库功能。
(2)对所有数据进行快速的矩阵计算
克服了循环繁琐的特点,写入数据与读取数据快。
(3)用于整合C/C++和Fortran代码的工具包
提供了一个非常易用的C语言API,使得数据传递给底层语言编写的外部库,在将计算结果按照NumPy数组的形式返回,传递给其他高级库处理更方便与简单。可以在底层语言中加入Python动态,易用的文件接口,进行数据处理功能。
(4)实用的线性代数、傅里叶变换和随机数生成函数
2.NumPy优点
NumPy本身不提供建模和科学函数,它的设计对于含有大量数组的数据非常有效,理解NumPy数组以及基于数组的计算将帮助我们更高效地使用基于数组的工具。
NumPy像其他语言一样,将数据存储在连续的内存块上,由于其算法库是用C语言写的,所以在操作数据内存时,不需要类型检查或者其他管理。其使用的内存量也小于其他Python内建数据结构序列。
NumPy最好用的是可以针对数组进行快速遍历,复杂计算而不需要写循环。这就节省了时间和内存。
3.数据结构和数据类型的区别
(1)数据类型
是一种值的集合和定义在这个值集上的一组操作的总称。
数据类型的分类为:原子类型和结构类型;
原子类型
= 一种值的集合 + 定义在值集合上的一组操作。(比如:python中的int,float,字符串)
结构类型
= 一种数据结构 + 定义在这种数据结构上的一组操作。(比如:python中的列表,字典,元组)
(2)数据结构
是相互之间存在一种或多种特定关系的数据元素的集合,包括逻辑结构和物理结构。
因此数据结构是一种数据类型。
4.NumPy数据类型
NumPy提供了N维数组类型ndarray
,是相同类型的数据的多维大数据集合。
ndarray在存储数据的时候,数据与数据的地址都是连续的,这样就给使得批量操作数组元素时速度更快。这种方法和C语言的数组一样,也就是用C语言的库来解决Python运行速度慢的问题。
因为ndarray中的所有元素的类型都是相同的(和C语言的数组类似),而Python列表中的元素类型是任意的,所以ndarray在存储元素时内存可以连续,而python内建数据结构list就只能通过寻址方式找到下一个元素。
这在一定程度上可能不够灵活,但用数组可以省掉好多循环语句,而且比较简单,速度快了好多倍。
三:NumPy ndarray
1.简介
NumPy的核心之一是N-维数组对象-ndarray。
它其实就是一个大型同类型数据集
,允许一些标量的操作方法(如加减乘除等)对其进行批量计算。
我们先生成一个二维数组,然后按照标量的操作语法进行操作:
这里我们使用标准的NumPy导入方式import numpy as np。这不是唯一的,但是一个习惯,一般都是这样导入的,这是为了方便里面的方法与Python内建函数的方法进行区别。
特点如下:
(1)大型数组集合
(2)多维
(3)相同类型
(4)类似标量操作语法
2.NumPy矩阵和数组区别
注:在NumPy中的,数组和矩阵是两个概念,matrix是array的分支,matrix和array在很多时候都是通用的,用哪一个都一样。但官方建议选择array,因为array更灵活,速度更快,很多人把二维的array也翻译成矩阵。
3.shape,dtype,ndim
每一个数组都有三个常用的属性,一个是shape属性,用来表示数组每一维的数量;一个是dtype属性,用来输出数组的数据类型;ndim输出形成的维数。
精通数组的编程和思考对于研究基于数组的数据分析是十分有用的。
4.生成ndarray
(1)基础创建方法
用array函数生成最简单的数组。
这里传到array的shape参数中,传的时一个元组,里面是每一维的个数
,该函数接受任意的序列对象(序列是是有索引,且默认索引是从0开始,可以分片,有通用的操作符的数据类型的统称,它们是数据结构+操作方法的数据类型)或者数组,生成一个新的包含传递数据的NumPy数组,还可以给参数dtype指定数据类型。
例如:
这里的二维数组可以看成是一个矩阵。
而不等长的序列会直接显示如下:
除非指定,否则np.array会自动推断生成数组的数据类型。其数据类型被存储在一个特殊的元数据dtype。
python默认的数据类型是float64(浮点型)
(2)其他方法
还有一些其他方法用于创建不同的数组:
函数名 | 说明 |
---|---|
asarray | 将输入转换为ndarray,但输入的已经是ndarray则不再复制 |
arange | Python内建函数range的数组版,返回一个数组 |
ones | 根据给定形状和数据类型生成全1数组 |
ones_like | 根据所给的数组生成一个形状一样的全1数组 |
zeros | 根据给定形状和数据类型生成全0数组 |
zeros_like | 根据所给的数组生成一个形状一样的全0数组 |
empty | 根据给定形状生成一个没有初始化数值的空数组 |
empty_like | 根据所给的数组生成一个形状一样但没有初始化数值的空数组 |
full | 根据给定形状和数据类型生成指定数值的数组 |
full_like | 根据所给的数组生成一个形状一样但内容是指定数值的数组 |
eye,identity | 生成一个特征矩阵(对角线位置都是1,其余位置是0) |
random.randn | 生成指定的的随机数组 |
5.ndarray的数据类型
数据类型dtype,包含了ndarray需要为某一类型数据所申明的内存块信息与数据的逻辑结构与物理结构,是结构类型的数据类型,又称为元数据(表示数据的数据)。
和其它语言的数据类型一样,可以用
astype方法
显式地转换数组的数据类型。注意在参数传递时尽量要加上np,这里要注意的是
使用numpy.string_类型作字符串数据要小心,因为NumPy会修正它的大小或删除输入且不发出警告
,如果转换类型出错会出现ValueError异常。
这里要注意,用
astype
转换类型时是生成一个新数组,也就是元数组的拷贝。
6.NumPy数组算术
(1)向量化
数组可以用标量的操作语法进行批量操作而无须用for循环,称之为向量化。
(2)相同尺寸数组算术操作
相同尺寸数组算术操作应用了逐元素操作的方式。如果带有标量的操作语法,都是这样的。
同尺寸数组之间比较,会产生一个布尔值数组。
(3)不同尺寸数组算术操作
不同尺寸数组算术操作用到了广播特性,在后面讲解时,会详细讲到。
7.ndarray数组索引与切片
(1)基础索引切片以及与序列的不同
对于一维数组,和序列的索引切片方法一样:
这里要注意,数组的切片是原数组的视图,和列表等序列有区别,它并不是被复制了,任何对数组的修改都会反映到原数组中:
下面用列表进行比较:
这里是由于如果数组的切片是复制的话,对于大数据处理的话就会引起内存问题。
(2)数组拷贝
如果只想得到一份数组切片的拷贝的话,就需要用到copy()函数。
(3)多维数组拷贝
对于多维数组,每个索引值获得的数据是下一层数组或者元素。可以用[,]代替[][]等,如下:
这里要注意的是,对于一个数组的索引和切片,返回的都是数组的视图,对其修改会体现到原视图上。
可以配合索引和切片使用,就可以得到低纬度的切片。
比如
list[a:b,c:d]
,就是选择第a->b-1行,列为c->d-1的数据,如下:
选择前两行,第三列的数据:
最好的方法就是先把其进行排列,排成二维表等,这里由于最常用的是二维数组,就先用二维数组进行说明。
(4)布尔索引
假设我们的数据都在数组中,如下一个数组:
我们的数组的比较操作也是可以向量化的,会生成一个布尔值数组。例如我们用(==)生成一个布尔值数组:
这时候,我们索引某个数组的时候,就可以用到这个布尔值数组了
,例如我们先创建一个随机数组:
然后用布尔值数组进行索引:
这里要注意的是,布尔值数组的长度要和要索引的数组的第一维长度相同。当不正确时,会报错:
还可以在索引值后面加上一个整数或切片,找到下一维对应的值:
还可以用!=或者~对布尔索引条件取反,表示选择找到布尔索引对应的行:
还可以对多个布尔值条件进行联合,要用到数学操作&(and)和|(or),选择多条件:
在这里,
使用布尔值索引选择数据时,是生成数组的拷贝,即使返回的数组并没有任何变化
,这个和Python的内置数据类型一样。
(5)神奇索引
先创建一个数组:
可以在索引时,简单地传递一个包含指明所需顺序的整数的列表或数组,如果是负整数索引,将从尾部进行选择:
这里要注意,索引是元组的话,选择的是指定数据
传递多个索引数组时,会根据每个索引到的元组对应的元素选出一个n维数组(看选取到了哪一级别),传了多少,就是几维。
比如有一个三维数组:
我们进行选择:
我们可以通过下面的方法,截取到我们想要的矩形区域:
在第二维及之后用到":":
上面的索引选择都可以重新复制,这里要注意的是,索引是复制了一份新的数组,而切片是原数组的视图,对切片的修改都会体现到原数组。
8.数组转置和换轴
数组转置会将二数组的行与列进行翻转,对于多维数组,会指定轴进行转换。在NumPy中,数轴转置与换轴有下面三种方式,他前两个返回的是数组的复制,最后一个返回的是数组的视图,对视图的修改会反映到原数组:
(1).T属性,适用于一,二维数组,如下:
(2)transpose高维数组转置
对于高维数组,transpose需要用到一个由轴编号组成的元组,这个就比较难理解。这里就是先看是多少维数组,然后从0开始编号。
如下,我们先创建一个三维数组,:
然后使用transpose函数:
就可以按照参数元组的规则,比如8原来的索引与现在的索引对比:
(3)swapaxes对换轴
可以用shape属性查看数组的每一维的个数,用swapaxes函数对索引对应的不同的两个维数的数据进行对换。如果是0和1对换,就相当于转置。如下:
这里要注意的是,swpaxes返回的是数据的视图,不是对数据的复制。
四:通用函数
通用函数是在数组中逐元素操作的函数,把一些标量函数进行向量化封装,应用到每一个元素中。
和Python的内建数据类型的方法没什么区别,只是作用于每一个元素了,就是
数组的函数
。
这里只介绍一些常用的函数:
一元数组的通用函数有:
函数名 | 描述 |
---|---|
sqrt | 计算每个元素的平方根(与array ** 0.5相等) |
exp | 计算每个元素的自然指数值 |
二元数组的通用函数有:
函数名 | 描述 |
---|---|
add | 讲两个数组的值进行相加,并返回一个数组作为结果,其他常见的操作函数这里省略 |
maxium | 比较两个元素的最大值,并返回一个数组作为结果,不忽略NaN |
fmax | 比较两个元素的最大值,并返回一个数组作为结果,忽略NaN |
minium | 比较两个元素的最小值,并返回一个数组作为结果,不忽略NaN |
fmin | 比较两个元素的最小值,并返回一个数组作为结果,忽略NaN |
上面的通用函数返回的都是一个数组,还有一些函数,返回的是多个数组。如modf,他返回了一个数组的小数和整数部分。如下:
五:数组向量化的一些方法
使用NumPy数组可以利用
简单的数组表达式
(函数参数,索引切片等)完成多种数据操作任务,而无须用大量循环。这种用
数组表达式
替代显式循环的方法称之为向量化。
下面就介绍一些数组向量化的方法。
1.条件逻辑
numpy.where是三元表达式x if a else b的向量化版本。它可以把一些条件选择的语句变得范围更广些,对于大数据来说,速度会快很多,而且适用于多维数组。
np.where有两种用法:
第一种是np.where(condition, x, y),即满足条件(condition),输出x,不满足输出y。这里0相当于False,1相当于True。
第二种是np.where(condition),只有条件 (condition),没有x和y,则输出满足条件 (即非0) 元素的坐标 这里的坐标以tuple的形式给出,通常原数组有多少维,输出的tuple中就包含几个数组,分别对应符合条件元素的各维坐标。这里的坐标就是从0开始的索引。
注:传递给np.where的数组既可以是同等大小的数组,也可以是标量。
2.数组和统计方法
在NumPy中,有许多计算整个数组统计值或关于某个轴的数据的函数。有两种写法,一种是直接调用数组实例的方法,一种是使用顶层的NumPy函数。
假设arr是某个数组,
第一种写法是:arr.function(),这里的function()为某个函数;
第二种写法是:np.function(arr),这里的function()为某个函数。
这些函数有的还可以接受一个可选参数axis,用于计算给定轴向上的统计值,形成一个下降一维的数组,可以省略axis,下面是一些方法:
方法 | 描述 |
---|---|
sum | 沿着某个轴计算所有元素的累和,空数组,累和为0 |
mean | 数学平均,空数组,平均值为NaN |
std,var | 标准差和方差,可以选择自由度调整(默认分母为n) |
min,max | 最大值和最小值 |
argmin,argmax | 最大值和最小值的位置 |
cumsum | 从0开始元素累积和 |
cumprod | 从1开始元素累积和 |
3.布尔值数组的方法
对于布尔值数组,有两个十分有用的方法,一个是any,一个是all。any检查数组中是否至少有一个True,而all检查数组中是否每个值是True,这些方法对于其他非布尔类型数组也有用。
我们先用==生成一个布尔值数组:
然后用这些函数:
4.排序
用
sort方法
进行NumPy数组排序,返回的是已经排序好的数组的拷贝。
5.一维数组基础集合操作
NumPy中包含了一些针对一维数组的基础集合操作,如下:
方法 | 描述 |
---|---|
unique(x) | 计算x的唯一值,并排序,得到的是拷贝 |
intersectld(x,y) | 计算x和y的交集,并排序 |
union1d(x,y) | 计算x和y的并集,并排序 |
inld(x,y) | 计算x中的元素是否包含在y中,返回一个布尔值数组 |
setdiffld(x,y) | 差集,在x中但不在y中的x的元素 |
setxorld(x,y) | 异或集,在x或y中,但不属于x,y交集的元素 |
6.使用数组进行文件输入和输出
在NumPy中,可以将数据以文本或二进制文件的形式存入硬盘或由硬盘载入。这里只展示NumPy内建二进制格式,由于大部分用户更喜欢用其他的工具载入文本或表格型数据。
np.save和np.load是高效存取硬盘数据的两个工具函数,数组在默认情况下是以压缩的格式进行存储的,后缀名为.npy,保存的都是二进制格式。
如果没有写.npy,则会被自动加上。可以用.load载入数据。
如下:
存入数据:
读取数据:
genfromtxt()函数可以从文本中读取数据并将其插入数组中,这个函数接收三个参数:存放数据的文件名、用于分隔值的字符和是否含有列标题。
这是NumPy的一些基本操作,之后会介绍更高级的操作。