numpy在深度学习或者数据分析中都是很常用的一个工具库,今天我结合自己的工作内容以及学习到的一个API的用法,来说下numpy的用法
数组(ndarray)与列表(List)
数组与列表类似,是具有相同类型的多个元素构成的整体。
局限:
- 数组元素要求是相同类型,而列表的元素可以是不同类型。
优势:
- 数组可以与标量进行运算,数组之间也可以进行矢量化运算。【对应位置的元素进行运算,无需进行循环操作。这样就可以充分利用现代处理器SIMD Single Instruction,Multiple Data的方式进行并行计算】。
- 数组在运算时,具有广播能力。【可根据需要进行元素的扩展,完成运算。】
- 数组底层使用C程序编写,运算速度快。
- 数组底层使用C中数组的存储方式(紧凑存储),节省内存空间。
应用对比
- 将两个等长的列表(数组)分别进行数学运算(例如,+, -等)。
- 将一个列表(数组)中的所有元素进行相同的改变。
- 对步骤2进行计时,衡量时间消耗。(练习)
- 创建相同大小的列表(数组),衡量内存消耗。(练习)
Numpy
NumPy(Numerical Python的简称),是科学计算基础的一个库,提供了大量关于科学计算的相关功能,例如,线性变换,数据统计,随机数生成等。其提供的最核心的类型为多维数组类型(ndarray)。
使用方式
可以使用如下的方式来安装numpy库:pip install numpy
根据惯例,使用numpy库的导入方式为:import numpy as np
在导入之后,我们可以通过:np.__version__
来查看Numpyu库的版本信息。
导入numpy
import numpy as np
数组的创建
Numpy提供了很多方式(函数)来创建数组对象,常用的方式如下:
- array 声明一个基本的数组 如:x = np.array([1,2]),y = np.array([[2,4],[4,5]])
- arange 指定start ,end,step
import numpy as np
c = np.arange(3,89,0.1)
- ones / ones_like 按照参数形状初始化numpy 初始化全为1
- zeros / zeros_like 初始化全为0
- empty / empty_like 指定大小的空矩阵
# 创建全为1的数组。
x = np.ones((5, 3))
# 创建与参数指定数组形状一致的数组,数组的值全为1。
y = np.ones_like(x)
# 创建全为0的数组。
x = np.zeros((2, 3))
# 创建与参数形状完全相同的数组,数组的值都为0。
y = np.zeros_like(x)
# print(y)
# 返回指定的形状的数组,数组的值是尚未初始化的值。(值多少是不确定的。)
x = np.empty((3, 8))
# 创建与参数形状完全相同的数组,数组的值是尚未初始化的值。
x = np.empty_like(x)
- full / full_like 这个函数用于数据填充,格式是args0 ,内容是args1如
x = np.full((2, 3), 100)
# np.ones((2, 3))
# 创建与参数形状完全相同的数组,数组的值使用第二个参数进行填充。
y = np.full_like(x, 200)
y
- eye / identity 对角单位方阵,对角线为1
- linspace 等差数组
- logspace 等比数组
np.linspace(1, 10, endpoint=False)
创建等比数列。(指数或对数上是一个等差数列,真实值就是一个等比数列。)
前两个参数表示指数,base表示底数(默认是10)。endpoint表示是否包含终止点(默认包含)。
np.logspace(1, 10, 10, base=2)
array([ 2., 4., 8., 16., 32., 64., 128., 256., 512.,1024.])
数组和numpy的速度对比,那个更快?
这个是毫无疑问的一般对于多维数组和矩阵来说矩阵操作更快一些,numpy提供的是矢量操作,多个值可以同时完成同一件事,而数据一般完成这种手段需要手动完成多个线程编写,或者单线程遍历,相对慢一些
相关属性与操作
数组对象具有如下常用属性:
- ndim
- shape
- dtype
- size
- itemsize
数据类型
- 在创建数组时,也可以使用dtype来显式指定数组中元素的类型(通过numpy提供的类型进行指定)。
- 如果没有指定,则会根据元素类型进行推断。
- 如果元素的类型不同,则会选择一种兼容的类型。
类型转换
我们可以通过数组对象的astype函数来进行类型转换。
是否可以直接修改dtype属性进行类型转换?
改变形状
我们可以通过数组对象的reshape方法(或者np的reshape函数)来改变数组的形状。
说明:
- 改变数组形状时,如果维度不小于2,可以将某一个维度设置为-1。
- numpy中存在很多方法,既可以使用np来访问,也可以通过数组对象来访问。
索引与切片
在Python中,序列类型支持索引与切片操作,在numpy库中,ndarray数组也支持类似的操作。不过,二者之间既有相同点,也有不同点。
相似点
数组对象也支持索引与切片操作,语法与Python中序列类型的索引与切片相似。
当数组是多维数组时,可以使用array[高维, 低维]的方式按维度进行索引或切片。
不同点
数组的切片返回的是原数组数据的视图(回忆:Python中呢?)。如果需要复制底层的数组元素,可以使用数组对象的copy方法。
注意:视图是共享底层的数组元素,但视图并不是赋值。
思考:通过切片,我们可以选取多个元素,但是,如果我们要选取的低维数组(或元素)是不连续的,该怎样做?
通过整数数组进行索引
当要选取的元素不连续时,可以提供一个索引数组来选择(或修改)对应索引位置的元素。
说明:
- 通过整数数组索引,返回的是原数组的拷贝,而不是视图。
- 可以提供多个一维数组索引,此时会将每个数组的对应位置元素作为索引,返回对应的元素。
通过布尔数组进行索引
我们可以提供一个布尔类型的数组(A),然后通过该数组(A)来对另外一个数组(B)进行索引(元素选取)。索引的原则为:如果为True,则选取对应位置的元素,否则不选取。
通过布尔类型的数组进行索引是常见且实用的操作,我们通常用来进行元素选择(或过滤)操作。例如:
- 选择一个公司中所有年龄大于15的年龄。
- 选择两个数组中对应位置相同的元素。
- 将所有大于100的值设置为100。
说明:
- 用于索引的布尔数组通常通过现有数组计算得出。
- 可以通过~对条件进行取反操作(不能使用not)。
- 当存在多个条件时,可以使用&,|符号(不能使用and与or),同时,每个条件需要使用()进行括起。
篇幅问题,下一篇会继续分享常见函数的用法!