Python之Numpy的超实用基础详细教程


Posted in Python onOctober 23, 2019

Numpy在python中属于非常常用的包,无论是机器学习搭配pandas,还是数据可视化搭配pylab都是很正常的搭配。

Numpy

numpy的官方中文文档:NumPy 中文

NumPy是使用Python进行科学计算的基础软件包。除其他外,它包括:

  • 功能强大的N维数组对象;
  • 精密广播功能函数;
  • 集成C/C+和Fortran代码的工具;
  • 强大的线性代数、傅立叶变换和随机数功能。

更简单的说,Numpy是Python的Matlab数学计算包。使用它,python可以更简单便捷地对矩阵向量进行计算。

一般来说,我们引用该包并将其简称为np:

import numpy as np

Numpy的ndarry对象

ndarray的创建

Numpy中最重要的数据类型就是:N维数组对象ndarray。它是一系列同类型数据的集合,以0下标为开始进行集合中元素的索引。

它具有以下两个特点:

  • ndarray对象是用于存放同类型元素的多维数组;
  • ndarray中的每个元素在内存中都有相同存储大小的区域。

创建一个ndarray对象:

np.array(object, dtype = None, copy = True, order = None, subok = False, ndmin = 0)

参数说明:

名称 描述
object 数组或嵌套的数列
dtype 数组元素的数据类型,可选
copy 对象是否需要复制,可选
order 创建数组的样式,C为行方向,F为列方向,A为任意方向(默认)
subok 默认返回一个与基类类型一致的数组
ndmin 指定生成数组的最小维度

一般而言,并不需要记住这么多可选参数:

import numpy as np

if __name__ == "__main__":
 x = np.array([1, 2, 3])
 print(x)

运行该脚本:

yngzmiao@yngzmiao-virtual-machine:~/test$ python numpy_test.py
[1 2 3]

当然,除了之前的array方法创建ndarray对象之外,还提供了另外的几种创建方式:

np.empty(shape, dtype = float, order = 'C')     # 指定形状的未初始化数组

np.zeros(shape, dtype = float, order = 'C')     # 指定形状的全0数组
np.ones(shape, dtype = None, order = 'C')      # 指定形状的全1数组

np.arange(start = 0, stop, step = 1, dtype)     # 从起始值到终止值(不包含)时,按步长从范围内创建数组

np.linspace(start, stop, num = 50, endpoint = True, retstep = False, dtype = None)  # 从起始值到终止值(默认包含)创建一个等差数组的一维数组
np.logspace(start, stop, num = 50, endpoint = True, base = 10.0, dtype = None) # 从起始值到终止值(默认包含)创建一个等比数组的一维数组

Numpy也提供了从python其他类型直接转换成ndarray的方式:

np.asarray(a, dtype = None, order = None)      # 列表形式
np.frombuffer(buffer, dtype = float, count = -1, offset = 0)      # 以流的形式读入
np.fromiter(iterable, dtype, count=-1)     # 从可迭代对象中,以迭代器的形式读入

例如:

import numpy as np

if __name__ == "__main__":
 a = [[1, 2 ,3], [4, 5]]
 b = 'Hello World'
 c = iter(range(5))

 x = np.asarray(a)
 y = np.frombuffer(b, dtype = 'S1')
 z = np.fromiter(c, dtype = float)

 print(x)
 print(y)
 print(z)

运行该脚本:

yngzmiao@yngzmiao-virtual-machine:~/test$ python numpy_test.py
[list([1, 2, 3]) list([4, 5])]
['H' 'e' 'l' 'l' 'o' ' ' 'W' 'o' 'r' 'l' 'd']
[0. 1. 2. 3. 4.]

ndarray的数据结构

Numpy支持很多的数据类型,下面就简单地列举一下:

名称 描述
bool_ 布尔型数据类型(True或者False)
int_/int8/int16/int32/int64 有符号整数
uint8/uint16/uint32/uint64 无符号整数
float_/float16/float32/float64 浮点数
complex_/complex64/complex128 复数

但如果是自定义的数据类型,就需要通过dtype来确定了:

numpy.dtype(object, align, copy)

参数说明:

名称 描述
object 要转换为的数据类型对象
align 如果为true,填充字段使其类似C的结构体
copy 复制dtype对象 ,如果为false,则是对内置数据类型对象的引用

例如,可以创建一个student的对象:

import numpy as np

if __name__ == "__main__":
 student = np.dtype([('name', 'S20'), ('age', 'i8'), ('score', 'f4')])
 a = np.array([('zhangsan', 18, 80), ('lisi', 19, 85)], dtype=student)
 print(a)

运行该脚本:

yngzmiao@yngzmiao-virtual-machine:~/test$ python numpy_test.py
[('zhangsan', 18, 80.) ('lisi', 19, 85.)]

ndarray的属性

ndarray有两个非常常用的属性,shape和size。shape表示数组的维度,对于二维数组而言,就是其行数和列数;size表示数组元素的总个数,对于二维数组而言,就是行数与列数的相乘。

例如:

import numpy as np

if __name__ == "__main__":
 a = np.array([[1, 2, 3], [4, 5, 6]])
 print(a.shape)
 print(a.size)

运行该脚本:

yngzmiao@yngzmiao-virtual-machine:~/test$ python numpy_test.py
(2, 3)
6

当然,ndarray对象提供了两种方式在不改变数据内容的情况下,改变一个数组的格式。但两种方式有所区别:

import numpy as np

if __name__ == "__main__":
 a = np.array([[1, 2, 3], [4, 5, 6]])
 a.shape = (3, 2)         # 直接改变本体
 print(a)
 b = a.reshape(2, 3)        # 本体不改变,将改变后的对象返回
 print(b)

运行该脚本:

yngzmiao@yngzmiao-virtual-machine:~/test$ python numpy_test.py
[[1 2]
 [3 4]
 [5 6]]
[[1 2 3]
 [4 5 6]]

ndarray的内容访问

ndarray对象的内容可以通过索引或切片来访问和修改,与python中list的切片操作一样。

ndarray既可以基于下标进行切片,也可以通过内置的slice函数,并设置start,stop及step参数进行,从原数组中切割出一个新数组。

例如:

import numpy as np

if __name__ == "__main__":
 a = np.arange(10)
 b = a[1:7:1]
 s = slice(1,7,1)
 c = a[s]

 print(a)
 print(b)
 print(c)

运行该脚本:

yngzmiao@yngzmiao-virtual-machine:~/test$ python numpy_test.py
[0 1 2 3 4 5 6 7 8 9]
[1 2 3 4 5 6]
[1 2 3 4 5 6]

对于冒号:的解释:

  • 如果是一维数组,如果只放置一个参数,如[2],将返回与该索引相对应的单个元素。如果为[2:],表示从该索引开始以后的所有项都将被提取。如果使用了两个参数,如[2:7],那么则提取两个索引(不包括停止索引)之间的项;
  • 如果是多维数组,使用,区分维数。

例如:

import numpy as np

if __name__ == "__main__":
 a = np.arange(25)
 a.shape = (5, 5)

 b = a[1:4, 2:4]
 print(a)
 print(b)

运行该脚本:

yngzmiao@yngzmiao-virtual-machine:~/test$ python numpy_test.py
[[ 0  1  2  3  4]
 [ 5  6  7  8  9]
 [10 11 12 13 14]
 [15 16 17 18 19]
 [20 21 22 23 24]]
[[ 7  8]
 [12 13]
 [17 18]]

ndarray除了基于下标进行切片,还有一些高级索引方式,比如布尔索引、花式索引。

例如:

import numpy as np

if __name__ == "__main__":
 a = np.arange(25)
 a.shape = (5, 5)

 b = a[a > 6]
 c = a[[3, 2, 4]]
 print(a)
 print(b)
 print(c)

运行该脚本:

yngzmiao@yngzmiao-virtual-machine:~/test$ python numpy_test.py
[[ 0  1  2  3  4]
 [ 5  6  7  8  9]
 [10 11 12 13 14]
 [15 16 17 18 19]
 [20 21 22 23 24]]
[ 7  8  9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24]
[[15 16 17 18 19]
 [10 11 12 13 14]
 [20 21 22 23 24]]

其他

判断元素对象是都为NaN:

np.isnan(...)

Numpy的广播

如果两个ndarray:a和b形状相同,即满足a.shape==b.shape,那么a与b的算数结果就是a与b数组对应位做算术运算。这要求维数相同,且各维度的长度相同。

例如:

import numpy as np

if __name__ == "__main__":
 a = np.array([1, 2, 3])
 b = np.array([1, 2, 3])
 c = a + b
 d = a * b
 
 print(c)
 print(d)

运行该脚本:

yngzmiao@yngzmiao-virtual-machine:~/test$ python numpy_test.py
[2 4 6]
[1 4 9]

而,广播是Numpy对不同形状(shape)的ndarray进行数值计算的方式,对ndarray的算术运算通常在相应的元素上进行

怎么才算是相应的元素呢?

虽然,广播是对不同形状(shape)而言,但其实还是要满足两个条件:列数相同,有一个行数为1。在这个前提下,每行的相同列的元素就是相对应的元素。

直接看文字可能还是有点不太能理解,可以看一下例子:

import numpy as np

if __name__ == "__main__":
 a = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
 b = np.array([1, 2, 3])
 c = a + b
 d = a * b
 
 print(c)
 print(d)

运行该脚本:

yngzmiao@yngzmiao-virtual-machine:~/test$ python numpy_test.py
[[ 2  4  6]
 [ 5  7  9]
 [ 8 10 12]]
[[ 1  4  9]
 [ 4 10 18]
 [ 7 16 27]]

所谓广播就是:当列数相同的时候,行数为1的ndarray会进行扩行的操作,增加的行数内容与原行的内容相同。

扩行的实现可以通过tile函数实现:

np.tile(obj, (行, 列))    # 在行上和列上分别重复一定的次数

所以,上文的广播也可以通过下面的方式来代替:

import numpy as np

if __name__ == "__main__":
 a = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
 b = np.array([1, 2, 3])
 bb = np.tile(b, (3, 1))
 c = a + bb
 d = a * bb
 
 print(bb)
 print(c)
 print(d)

运行该脚本:

yngzmiao@yngzmiao-virtual-machine:~/test$ python numpy_test.py
[[1 2 3]
 [1 2 3]
 [1 2 3]]
[[ 2  4  6]
 [ 5  7  9]
 [ 8 10 12]]
[[ 1  4  9]
 [ 4 10 18]
 [ 7 16 27]]

ndarray的函数

ndarray提供了很多的数学函数、算术函数、排序函数,以便进行运算。

ndarray的数学函数,例如:

np.pi          # 圆周率
np.sin(obj)       # 三角运算
np.cos(obj)
np.tan(obj)
np.arcsin(obj)     # 反三角运算
np.arccos(obj)
np.arctan(obj)
np.degrees(obj)     # 将弧度值转换为角度值

np.around(obj, decimals) # 返回ndarray每个元素的四舍五入值,decimals为舍入的小数位数,默认为0
np.floor(obj)      # 向下取整
np.ceil(obj)      # 向上取整

ndarray的算术函数,例如:

np.add(obj1, obj2)        # 加减乘除运算,与+-*/效果一致,需要符合广播原则
np.subtract(obj1, obj2)
np.multiply(obj1, obj2)
np.divide(obj1, obj2)
np.mod(obj1, obj2)        # 求余数运算

np.reciprocal(obj)        # 元素取倒数

np.power(obj1, obj2)       # 计算前参数为底,后参数为幂的值

ndarray的排序函数,例如:

np.sort(obj, axis=1, kind='quicksort', order)

参数说明:

名称 描述
obj 数组或嵌套的数列
axis axis=0按列排序,axis=1按行排序
kind ‘quicksort'、‘mergesort'、‘heapsort'
order 如果数组包含字段,则是要排序的字段

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
学习python (1)
Oct 31 Python
python操作xml文件详细介绍
Jun 09 Python
python字典多键值及重复键值的使用方法(详解)
Oct 31 Python
python使用matplotlib绘图时图例显示问题的解决
Apr 27 Python
python实现随机梯度下降(SGD)
Mar 24 Python
python逐行读写txt文件的实例讲解
Apr 03 Python
用Python分析3天破10亿的《我不是药神》到底神在哪?
Jul 12 Python
解决Python print 输出文本显示 gbk 编码错误问题
Jul 13 Python
使用python将多个excel文件合并到同一个文件的方法
Jul 09 Python
详解程序意外中断自动重启shell脚本(以Python为例)
Jul 26 Python
浅谈Selenium 控制浏览器的常用方法
Dec 04 Python
详解matplotlib绘图样式(style)初探
Feb 03 Python
Python从列表推导到zip()函数的5种技巧总结
Oct 23 #Python
Python箱型图绘制与特征值获取过程解析
Oct 22 #Python
Python使用贪婪算法解决问题
Oct 22 #Python
python元组和字典的内建函数实例详解
Oct 22 #Python
Python List列表对象内置方法实例详解
Oct 22 #Python
Python序列对象与String类型内置方法详解
Oct 22 #Python
Python基本语法之运算符功能与用法详解
Oct 22 #Python
You might like
PHP 5.0对象模型深度探索之绑定
2006/09/05 PHP
兼容ie6浏览器的php下载文件代码分享
2014/07/14 PHP
typecho插件编写教程(二):写一个新插件
2015/05/28 PHP
jQuery AJAX实现调用页面后台方法和web服务定义的方法分享
2012/03/01 Javascript
js 获取坐标 通过JS得到当前焦点(鼠标)的坐标属性
2013/01/04 Javascript
JS验证邮件地址格式方法小结
2015/12/01 Javascript
JavaScript+html5 canvas绘制的小人效果
2016/01/27 Javascript
Bootstrap安装环境配置教程分享
2016/05/27 Javascript
canvas实现刮刮卡效果
2017/03/14 Javascript
JS触摸事件、手势事件详解
2017/05/04 Javascript
vue的常用组件操作方法应用分析
2018/04/13 Javascript
jquery 验证用户名是否重复代码实例
2019/05/14 jQuery
深入学习Vue nextTick的用法及原理
2019/10/08 Javascript
Json实现传值到后台代码实例
2020/06/30 Javascript
谈一谈vue请求数据放在created好还是mounted里好
2020/07/27 Javascript
基于vue实现简易打地鼠游戏
2020/08/21 Javascript
[04:20]DOTA2-DPC中国联赛 正赛 VG vs LBZS 选手采访 1月19日
2021/03/11 DOTA
python开发之thread线程基础实例入门
2015/11/11 Python
基于asyncio 异步协程框架实现收集B站直播弹幕
2016/09/11 Python
浅谈Python的垃圾回收机制
2016/12/17 Python
Python编程判断这天是这一年第几天的方法示例
2017/04/18 Python
python-opencv在有噪音的情况下提取图像的轮廓实例
2017/08/30 Python
python提取log文件内容并画出图表
2019/07/08 Python
Python 读取用户指令和格式化打印实现解析
2019/09/02 Python
Windows下PyCharm2018.3.2 安装教程(图文详解)
2019/10/24 Python
python isinstance函数用法详解
2020/02/13 Python
加拿大知名的国际儿童品牌:Hatley
2016/11/09 全球购物
全世界最美丽的四星和五星级酒店预订:Prestigia.com
2017/11/15 全球购物
全球在线商店:BerryLook
2019/04/14 全球购物
什么是动态端口(Dynamic Ports)?动态端口的范围是多少?
2014/12/12 面试题
办加油卡单位介绍信
2014/01/09 职场文书
客服部班长工作责任制
2014/02/25 职场文书
平遥古城导游词
2015/02/03 职场文书
高一作文之乐趣
2019/11/21 职场文书
Vertica集成Apache Hudi重磅使用指南
2022/03/31 Servers
Java 多线程协作作业之信号同步
2022/05/11 Java/Android