Python之Numpy的超实用基础详细教程
Numpy在python中属于非常常用的包,无论是机器学习搭配pandas,还是数据可视化搭配pylab都是很正常的搭配。
Numpy
numpy的官方中文文档:NumPy 中文
NumPy是使用Python进行科学计算的基础软件包。除其他外,它包括:
- 功能强大的N维数组对象;
- 精密广播功能函数;
- 集成C/C+和Fortran代码的工具;
- 强大的线性代数、傅立叶变换和随机数功能。
更简单的说,Numpy是Python的Matlab数学计算包。使用它,python可以更简单便捷地对矩阵向量进行计算。
一般来说,我们引用该包并将其简称为np:
1
|
import numpy as np |
Numpy的ndarry对象
ndarray的创建
Numpy中最重要的数据类型就是:N维数组对象ndarray。它是一系列同类型数据的集合,以0下标为开始进行集合中元素的索引。
它具有以下两个特点:
- ndarray对象是用于存放同类型元素的多维数组;
- ndarray中的每个元素在内存中都有相同存储大小的区域。
创建一个ndarray对象:
1
|
np.array( object , dtype = None , copy = True , order = None , subok = False , ndmin = 0 ) |
参数说明:
名称 | 描述 |
---|---|
object | 数组或嵌套的数列 |
dtype | 数组元素的数据类型,可选 |
copy | 对象是否需要复制,可选 |
order | 创建数组的样式,C为行方向,F为列方向,A为任意方向(默认) |
subok | 默认返回一个与基类类型一致的数组 |
ndmin | 指定生成数组的最小维度 |
一般而言,并不需要记住这么多可选参数:
1 2 3 4 5
|
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对象之外,还提供了另外的几种创建方式:
1 2 3 4 5 6 7 8 9
|
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的方式:
1 2 3
|
np.asarray(a, dtype = None , order = None ) # 列表形式 np.frombuffer( buffer , dtype = float , count = - 1 , offset = 0 ) # 以流的形式读入 np.fromiter(iterable, dtype, count = - 1 ) # 从可迭代对象中,以迭代器的形式读入 |
例如:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
|
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来确定了:
1
|
numpy.dtype( object , align, copy) |
参数说明:
名称 | 描述 |
---|---|
object | 要转换为的数据类型对象 |
align | 如果为true,填充字段使其类似C的结构体 |
copy | 复制dtype对象 ,如果为false,则是对内置数据类型对象的引用 |
例如,可以创建一个student的对象:
1 2 3 4 5 6
|
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表示数组元素的总个数,对于二维数组而言,就是行数与列数的相乘。
例如:
1 2 3 4 5 6
|
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对象提供了两种方式在不改变数据内容的情况下,改变一个数组的格式。但两种方式有所区别:
1 2 3 4 5 6 7 8
|
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参数进行,从原数组中切割出一个新数组。
例如:
1 2 3 4 5 6 7 8 9 10 11
|
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],那么则提取两个索引(不包括停止索引)之间的项;
- 如果是多维数组,使用,区分维数。
例如:
1 2 3 4 5 6 7 8 9
|
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除了基于下标进行切片,还有一些高级索引方式,比如布尔索引、花式索引。
例如:
1 2 3 4 5 6 7 8 9 10 11
|
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:
1
|
np.isnan(...) |
Numpy的广播
如果两个ndarray:a和b形状相同,即满足a.shape==b.shape,那么a与b的算数结果就是a与b数组对应位做算术运算。这要求维数相同,且各维度的长度相同。
例如:
1 2 3 4 5 6 7 8 9 10 11
|
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。在这个前提下,每行的相同列的元素就是相对应的元素。
直接看文字可能还是有点不太能理解,可以看一下例子:
1 2 3 4 5 6 7 8 9 10
|
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函数实现:
1
|
np.tile(obj, (行, 列)) # 在行上和列上分别重复一定的次数 |
所以,上文的广播也可以通过下面的方式来代替:
1 2 3 4 5 6 7 8 9 10 11 12
|
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的数学函数,例如:
1 2 3 4 5 6 7 8 9 10 11 12
|
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的算术函数,例如:
1 2 3 4 5 6 7 8 9
|
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的排序函数,例如:
1
|
np.sort(obj, axis = 1 , kind = 'quicksort' , order) |
参数说明:
名称 | 描述 |
---|---|
obj | 数组或嵌套的数列 |
axis | axis=0按列排序,axis=1按行排序 |
kind | ‘quicksort'、‘mergesort'、‘heapsort' |
order | 如果数组包含字段,则是要排序的字段 |
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。
也许是最全java资料!(文档+项目+资料)【点击下载】 和努力的人一起学习Java!