前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布

Numpy

作者头像
小闫同学啊
发布2019-07-18 15:27:08
9710
发布2019-07-18 15:27:08
举报
文章被收录于专栏:小闫笔记小闫笔记

正文共: 5937 字 5 图 预计阅读时间: 15 分钟

每日分享

You cannot protect yourself from sadness without protecting yourself from happiness.

稳不住幸福,亦躲不过悲伤。

Numpy

1.简单了解Numpy

Numpy是一个开源的Python科学计算库,用于快速处理任意维度的数组,支持常见的数组和矩阵操作。

使用Numpy需要先安装这个模块。

Numpy使用 ndarray对象来处理多维数组,而且 ndarray中所有元素的类型都是相同的。我们先来看看怎么创建一个 ndarray

代码语言:javascript
复制
import numpy as np
np.array(列表)

注意:本文中所使用的np都指 numpy

2.Numpy的优势

2.1内存块的分割

ndarray在存储数据的时候,数据与数据的地址都是连续的,一体式存储使得批量操作数组元素的时候速度更快。而python中的列表元素类型是任意的,采用分离式存储,这样就使得list只能通过地址方式找到下一个元素。因此 numpyndarray在科学计算中大放异彩。

2.2ndarray支持并行化运算(向量化运算)

2.3解除了GIL

numpy底层使用了C语言编写,内部解除了GIL,其对数组的操作速度不受python解释器的限制,所以其效率远高于纯python代码。

3.N维数组-ndarray

3.1属性

ndarray.shape代表的是数组维度的元组。

代码语言:javascript
复制
In [3]: np.array([[1,2,3],[4,5,6]]).shape
Out[3]: (2, 3)   # 二维数组

ndarray.ndim代表的是数组维数。

代码语言:javascript
复制
In [4]: np.array([[1,2,3],[4,5,6]]).ndim
Out[4]: 2

ndarray.size代表的是数组中元素数量。

代码语言:javascript
复制
In [5]: np.array([[1,2,3],[4,5,6]]).size
Out[5]: 6

ndarray.itemsize代表的是一个数组元素的长度(字节)。

代码语言:javascript
复制
In [7]: np.array([[1,2,3],[4,5,6]]).itemsize
Out[7]: 8

ndarray.dtype代表的是数组元素类型。

代码语言:javascript
复制
In [8]: np.array([[1,2,3],[4,5,6]]).dtype
Out[8]: dtype('int64')

3.2形状

数组分为一维数组、二位数组、三维数组到N维数组。一维数组类似是线性结构;二维数组则是有两个方向,可以简单的理解为咱们的表;三维数组则可以理解为多张表在另一个方向的叠加。N维数组无法比喻。

3.3类型

我们上面说过了, dtype属性即元素类型,我们也知道 ndarray中的元素类型一致,那么类型都有哪些呢?看下面表格:

名称

描述

简写

np.bool

用一个字节存储的布尔类型(True或False)

'b'

np.int8

一个字节大小,-128 至 127

'i'

np.int16

整数,-32768 至 32767

'i2'

np.int32

整数,-2^31 至 2^31 -1

'i4'

np.int64

整数,-2^63 至 2^63 - 1

'i8'

np.uint8

无符号整数,0 至 255

'u'

np.uint16

无符号整数,0 至 65535

'u2'

np.uint32

无符号整数,0 至 2^32 - 1

'u4'

np.uint64

无符号整数,0 至 2^64 - 1

'u8'

np.float16

半精度浮点数:16位,正负号1位,指数5位,精度10位

'f2'

np.float32

单精度浮点数:32位,正负号1位,指数8位,精度23位

'f4'

np.float64

双精度浮点数:64位,正负号1位,指数11位,精度52位

'f8'

np.complex64

复数,分别用两个32位浮点数表示实部和虚部

'c8'

np.complex128

复数,分别用两个64位浮点数表示实部和虚部

'c16'

np.object_

python对象

'O'

np.string_

字符串

'S'

np.unicode_

unicode类型

'U'

我们创建数组的时候可以指定类型:

代码语言:javascript
复制
In [17]: np.array(['python','ethanyan'],dtype=np.string_).dtype
Out[17]: dtype('S8')

注意:如果不指定类型,整数默认是 int64,小数默认是 float64

4.基本操作

4.1生成数组

4.1.1生成0和1的数组
代码语言:javascript
复制
np.zeros()
np.ones()
np.zeros_like()
np.ones_like()

以生成0的数组为例:

代码语言:javascript
复制
In [18]: np.zeros([3,4])
Out[18]: 
array([[0., 0., 0., 0.],
       [0., 0., 0., 0.],
       [0., 0., 0., 0.]])
In [19]: np.zeros_like([[1,2],[1,1]])
Out[19]: 
array([[0, 0],
       [0, 0]])

可以看到 zeros中指定数组的形状维度,而 zeros_like是传入一个数组,仿照其形状生成一个新的数组。

4.1.2从现有的数组中生成
代码语言:javascript
复制
a = np.array([[1,2,3],[4,5,6]])
# 从现有的数组当中创建
a1 = np.array(a)
# 相当于索引的形式,并没有真正的创建一个新的
a2 = np.asarray(a)

需要传入一个数组,然后生成一个一模一样的数组。 array类似于深拷贝, asarray则类似于浅拷贝。

4.1.3生成固定范围的数组
代码语言:javascript
复制
np.linspace(start,stop,num,endpoint)
# start 序列的起始值
# stop 序列的终止值,
# num 要生成的等间隔样例数量,默认为50
# endpoint 序列中是否包含stop值,默认为ture
np.arange(start,stop, step, dtype)
np.logspace(start,stop, num)

linspace生成等间隔的数组,其中num指定的是生成的数组中有多少个样例。

代码语言:javascript
复制
In [21]: np.linspace(0,100,11)
Out[21]: array([  0.,  10.,  20.,  30.,  40.,  50.,  60.,  70.,  80.,  90., 100.])

arange生成固定间隔的数组,其中的step指的是间隔大小。

代码语言:javascript
复制
In [22]: np.arange(10,50,2)
Out[22]: 
array([10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32, 34, 36, 38, 40, 42,44, 46, 48])

logspace生成的则是10的指数的数据。

代码语言:javascript
复制
In [23]: np.logspace(0,2,3)
Out[23]: array([  1.,  10., 100.])

其中0,2代表的是从 10^010^2也就是1到100。3指的是生成固定间隔的3个样例。

4.1.4生成随机数组

生成均匀分布数组:

代码语言:javascript
复制
np.random.uniform(low, high, size)
# low: 采样下界,float类型,默认值为0;
# high: 采样上界,float类型,默认值为1;
# size: 输出样本数目,为int或元组(tuple)类型。缺省时输出1个值。
# 返回值:ndarray类型,其形状和参数size中描述一致。例如,size=(m,n,k),仿照我们之前看到的维度的元组。

上面的功能是从一个均匀分布左开右闭的区间 [low,high)中随机采样。

生成正态分布数据:

代码语言:javascript
复制
np.random.normal(loc=0.0, scale=1.0, size=None)
# loc:float;此概率分布的均值(对应着整个分布的中心centre)
# scale:float;此概率分布的标准差(对应于分布的宽度,scale越大越矮胖,scale越小,越瘦高)
# size:int or tuple of ints;输出的shape,默认为None,只输出一个值

4.2数组的索引和切片

我们用一个难一点的例子来说明一下:

代码语言:javascript
复制
In [25]: a1 = np.array([ [[1,2,3],[4,5,6]], [[12,3,34],[5,6,7]]])
In [26]: a1        
Out[26]: 
array([[[ 1,  2,  3],
        [ 4,  5,  6]],

       [[12,  3, 34],
        [ 5,  6,  7]]])
In [27]: a1[0,0,1]
Out[27]: 2

注意:获取的时候先行后列,直接通过 []获取即可。

4.3形状修改

代码语言:javascript
复制
对象.reshape(shape)
# shape代表的是要转换成的数组的形状
# shape可以不指定行或者列,然后通过-1表示。最后的结果计算机自动计算,但是结果必须可以整除,不能来一个1.5行的数组。
# 如:[-1,20]代表的是不知道多少行,但是生成20列。

注意:没有进行行列互换,而是按顺序原先元素顺序重新分组,新产生了一个 ndarray

代码语言:javascript
复制
对象.resize()

注意:没有进行行列互换,而且是在原来的 ndarray上修改。

代码语言:javascript
复制
对象.T

注意:进行了行列互换,而且产生了新的 ndarray

4.4类型修改

代码语言:javascript
复制
ndarray.astype(type)
ndarray.tostring()
ndarray.tobytes()

4.5数组去重

代码语言:javascript
复制
np.unique(ndarray)

例如:

代码语言:javascript
复制
In [28]: np.unique(np.array([[1, 2, 3, 4],[3, 4, 5, 6]]))    
Out[28]: array([1, 2, 3, 4, 5, 6])

5.ndarray运算

5.1逻辑运算

可以直接通过大于号小于号进行运算,返回的是一个数组,其中符合条件的地方标记为True,不符合条件的地方标记为False。

5.2通用判断函数

判断所有元素是否符合条件,如果符合返回True,反之False。

代码语言:javascript
复制
np.all()

判断其中是否有满足条件的元素,有则返回True。

代码语言:javascript
复制
np.any()

5.3三元运算符

我们可以使用 where来进行更加复杂的运算。比如我们判断股票的涨跌幅,数据为 temp,大于0的置为1,否则为0。

代码语言:javascript
复制
np.where(temp > 0, 1, 0)

还可以进行更加复杂的判断。结合两个函数的使用。 np.logical_andnp.logical_or代表的是与和或。

代码语言:javascript
复制
# 判断股票涨跌幅 大于0.5并且小于1的,换为1,否则为0
np.where(np.logical_and(temp > 0.5, temp < 1), 1, 0)
# 判断股票涨跌幅 大于0.5或者小于-0.5的,换为1,否则为0
np.where(np.logical_or(temp > 0.5, temp < -0.5), 1, 0)

5.4统计运算

np.max()是最大。

np.main()是最小。

np.std是标准差。

np.mean()是平均值。

np.argmax()是数组中最大值的位置。

np.argmin()是数组中最小值的位置。

注意:在运算的函数里都有一个参数axis,其中0代表列,1代表行。

6.数组间的运算

6.1数组和数的运算

代码语言:javascript
复制
In [29]: arr = np.array([[1,2,3,2,1,4],[5,6,1,2,3,1]])
In [30]: arr + 1
Out[30]: 
array([[2, 3, 4, 3, 2, 5],
       [6, 7, 2, 3, 4, 2]])
In [31]: arr / 2
Out[31]: 
array([[0.5, 1. , 1.5, 1. , 0.5, 2. ],
       [2.5, 3. , 0.5, 1. , 1.5, 0.5]])

可以看到数组和数能进行计算,而且类似咱们线性代数中的矩阵运算。

6.2数组和数组运算

数组和数组之间的运算符合广播机制。那么什么是广播机制呢?

在进行矩阵运算的时候,我们都知道加法是行列相等的时候才可以进行,而且对应位置元素进行加法运算。进行乘法的时候,m×n 的矩阵乘以 n×1 的向量,得到的是 m×1 的向量。

在数组与数组进行运算的时候,如果两个数组形状不相等,我们可以通过扩展数组的方法来实现相加减等运算,这种机制就是广播机制。但是它也是有原则的人,并不是所有的数组都可以进行运算的。只有符合下面情况,才可以:

1.维度相同,其中有个对应的轴长为1。

给大家举个例子。比如有两个数组,他们的shape分别为(4,3)和(4,1)。或者shape分别为(3,5,6)和(3,1,6)。再或者(1,2,1)和(5,2,6)。他们都符合维度相同,在不同轴上,要么相同,要么对应的轴有一个为1。

2.维度不相同,后缘维度(从末尾开始算起的维度)的轴长相同。

同样举例子说明。两个数组分别为(256,256,3)和(3,),虽然维度不同,但是都从尾部开始算,后一个数组后缘维度的轴长为3,前一个数组也是如此,符合广播机制可以运算。再比如(12,5,2)和(5,2)。

3.前两条可以综合。如(9,1,7,1)和(8,1,5)也符合广播机制,可以运算。

代码语言:javascript
复制
9 x 1 x 7 x 1
    8 x 1 x 5

6.3矩阵乘法

矩阵乘法有两个api,分别是:

代码语言:javascript
复制
np.matmul(a,b)  # a和b为两个数组
np.dot(a,b)

我们先来演示一下:

代码语言:javascript
复制
In [35]: a = np.array([[80, 86], 
    ...: [82, 80], 
    ...: [85, 78], 
    ...: [90, 90], 
    ...: [86, 82], 
    ...: [82, 90], 
    ...: [78, 80], 
    ...: [92, 94]])
In [36]: b = np.array([[0.7],[0.3]])
In [37]: np.matmul(a,b)
Out[37]: 
array([[81.8],
       [81.4],
       [82.9],
       [90. ],
       [84.8],
       [84.4],
       [78.6],
       [92.6]])
In [39]: np.dot(a,b)
Out[39]: 
array([[81.8],
       [81.4],
       [82.9],
       [90. ],
       [84.8],
       [84.4],
       [78.6],
       [92.6]])

可以看到两种方法在计算上面的例子时,结果一样。那么他们有区别吗?答案是肯定的。

区别

np.matmul中禁止矩阵与标量的乘法。 在矢量乘矢量的內积运算中, np.matmulnp.dot没有区别。

6.4矩阵应用场景

大部分的机器学习算法都需要用到矩阵。当然也不难理解,算法嘛,为什么很多岗位招的是计算机或者数学,因为算法运用的都是数学知识,计算机像这些模块只是工具,算法数学才是精髓。

优质文章推荐:

公众号使用指南

redis操作命令总结

前端中那些让你头疼的英文单词

Flask框架重点知识总结回顾

项目重点知识点详解

难点理解&面试题问答

flask框架中的一些常见问题

团队开发注意事项

浅谈密码加密

Django框架中的英文单词

Django中数据库的相关操作

DRF框架中的英文单词

重点内容回顾-DRF

Django相关知识点回顾

美多商城项目导航帖

项目重要技术点介绍

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2019-04-08,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 全栈技术精选 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 每日分享
  • Numpy
    • 1.简单了解Numpy
      • 2.Numpy的优势
        • 2.1内存块的分割
        • 2.2ndarray支持并行化运算(向量化运算)
        • 2.3解除了GIL
      • 3.N维数组-ndarray
        • 3.1属性
        • 3.2形状
        • 3.3类型
      • 4.基本操作
        • 4.1生成数组
        • 4.2数组的索引和切片
        • 4.3形状修改
        • 4.4类型修改
        • 4.5数组去重
      • 5.ndarray运算
        • 5.1逻辑运算
        • 5.2通用判断函数
        • 5.3三元运算符
        • 5.4统计运算
      • 6.数组间的运算
        • 6.1数组和数的运算
        • 6.2数组和数组运算
        • 6.3矩阵乘法
        • 6.4矩阵应用场景
    领券
    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档