加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > Python > 正文

【Numpy】数组的计算1

发布时间:2020-12-20 10:53:11 所属栏目:Python 来源:网络整理
导读:Numpy数组的计算:通用函数 Numpy数组的计算有时非常快,有时也非常慢,使Numpy变快的关键是利用向量化的操作,通常在Numpy的通用函数中实现,提高数组元素的重复计算的效率 缓慢的循环 Pythom的默认实现(被称为Cpython)处理某种操作时非常慢,一部分原因

Numpy数组的计算:通用函数

Numpy数组的计算有时非常快,有时也非常慢,使Numpy变快的关键是利用向量化的操作,通常在Numpy的通用函数中实现,提高数组元素的重复计算的效率

缓慢的循环

Pythom的默认实现(被称为Cpython)处理某种操作时非常慢,一部分原因是该语言的动态性和解释性-数据类型的灵活特性决定了序列操作不能像C语言和Fortan语言一样被编译成有效的机器码

Python的相对缓慢通常出现在很多小操作需要不断重复的时候,比如对数组的每个元素做循环操作时。

事实上处理的瓶颈并不是运算本身,而是Cpython在每次循环时都必须做数据类型的检查和函数的调度,并没有静态语言运行前编译这样更有效率

通用函数介绍

Numpy为很多类型的操作提供了非常方便的,静态类型的,可编译程序的接口。也被称作向量操作,可以通过简单地对数组进行操作,这样会用于数组的每一个元素

Numpy的向量操作是通过通用函数实现的,通用函数的主要目的是对Numpy数组中的值执行更快的重复操作

1 np.arange(5) / np.arange(1,6)
2 Out[85]: array([0.,0.5,0.66666667,0.75,0.8       ])

不仅限于一维数组,可以进行多维数组的计算

1 x = np.arange(9).reshape((3,3))
2 
3 2 ** x
4 Out[87]: 
5 array([[  1,2,4],6        [  8,16,32],7        [ 64,128,256]],dtype=int32)

通过通用函数用向量的方式进行计算几乎总比用Python循环实现的计算更有效率,尤其是数组很大时。

Numpy的通用函数

通用函数有两种存在形式:一元通用函数对单个输入操作,二元通用函数对两个输入操作

1.数组的计算

 1 x = np.arange(4)
 2 
 3 print("x  =",x)
 4 x  = [0 1 2 3]
 5 
 6 print("x + 5",x + 5)
 7 x + 5 [5 6 7 8]
 8 
 9 print("x - 5",x - 5)
10 x - 5 [-5 -4 -3 -2]
11 
12 print("x * 2",x * 2)
13 x * 2 [0 2 4 6]
14 
15 print("x / 2",x / 2)
16 x / 2 [0.  0.5 1.  1.5]
17 
18 print("x // 2",x // 2)
19 x // 2 [0 0 1 1]
20 
21 print("-x =",-x)
22 -x = [ 0 -1 -2 -3]
23 
24 print("x **2",x ** 2)
25 x **2 [0 1 4 9]
26 
27 print("x % x",x % 2)
28 x % x [0 1 0 1]

可以任意将这些运算符组合使用,当然需要考虑优先级

1 - (0.5 * x + 1) ** 2
2 Out[98]: array([-1.,-2.25,-4.,-6.25])

所有这些算数运算符都是Numpy内置函数的简单封装器,例如+运算符就是add函数的封装器:

1 np.add(x,2)
2 Out[99]: array([2,3,4,5])

Numpy实现的算术运算符

1 运算符       对应的通用函数  
2 +             np.add
3 -             no.subtract
4 -             np.negative
5 /             np.divide
6 //            np.floor_divide
7 **            np.power
8 %             np.mod

2.绝对值

1 x = np.array([-2,-1,1,2])
2 
3 abs(x)
4 Out[101]: array([2,2])
5 
6 x
7 Out[102]: array([-2,2])

对应的Numpy通用函数是np.absolute,该函数也可以用别名np.abs来访问:

1 np.absolute(x)
2 Out[103]: array([2,2])
3 
4 np.abs(x)
5 Out[104]: array([2,2])

这个通用函数也可以处理复数,当处理复数时,绝对值返回的是该复数的模

1 x = np.array([3 - 4j,4 - 3j,2 + 0j,0 + 1j])
2 
3 np.abs(x)
4 Out[106]: array([5.,5.,2.,1.])

3.三角函数

首先定义一个角度数组:

1 theta = np.linspace(0,np.pi,3)

对这些值进行三角函数运算:

 1 print("theta  =",theta)
 2 theta  = [0.         1.57079633 3.14159265]
 3 
 4 print("sin(theta) =",np.sin(theta))
 5 sin(theta) = [0.0000000e+00 1.0000000e+00 1.2246468e-16]
 6 
 7 print("cos(theta) =",np.cos(theta))
 8 cos(theta) = [ 1.000000e+00  6.123234e-17 -1.000000e+00]
 9 
10 print("tan(theta) =",np.tan(theta))
11 tan(theta) = [ 0.00000000e+00  1.63312394e+16 -1.22464680e-16]

逆三角函数同样可以使用:

 1 x = [-1,1]
 2 
 3 print("x  =",x)
 4 x  = [-1,1]
 5 
 6 print("arcsin(x) =",np.arcsin(x))
 7 arcsin(x) = [-1.57079633  0.          1.57079633]
 8 
 9 print("arccos(x) =",np.arccos(x))
10 arccos(x) = [3.14159265 1.57079633 0.        ]
11 
12 print("arctan(x) =",np.arctan(x))
13 arctan(x) = [-0.78539816  0.          0.78539816]

4.指数和对数

Numpy中另一个常用的运算通用函数是指数运算

 1 x = [1,3]
 2 
 3 print("x  =",x)
 4 x  = [1,3]
 5 
 6 print("e^2 =",np.exp(x))
 7 e^2 = [ 2.71828183  7.3890561  20.08553692]
 8 
 9 print("2^x =",np.exp2(x))
10 2^x = [2. 4. 8.]
11 
12 print("3^x =",np.power(3,x))
13 3^x = [ 3  9 27]

指数运算的逆运算,即取对数也是可用的

最基本的np.log给出的是以自然常数(e)为底数的对数

 1 x = [1,10]
 2 
 3 print("x   =",x)
 4 x   = [1,10]
 5 
 6 print("ln(x) =",np.log(x))
 7 ln(x) = [0.         0.69314718 1.38629436 2.30258509]
 8 
 9 print("log2(x) =",np.log2(x))
10 log2(x) = [0.         1.         2.         3.32192809]
11 
12 print("log10(x) =",np.log10(x))
13 log10(x) = [0.         0.30103    0.60205999 1.        ]

还有一些特殊版本,对非常小的输入值可以保持较好的精度:

1 x = [0,0.001,0.01,0.1]
2 
3 print("exp(x) - 1 =",np.expm1(x))
4 exp(x) - 1 = [0.         0.0010005  0.01005017 0.10517092]
5 
6 print("log(1 + x) =",np.log1p(x))
7 log(1 + x) = [0.         0.0009995  0.00995033 0.09531018]

当x的值很小时,以上函数给出的值比np.log和np.exp的计算更精确

5.专用的通用函数

介绍一个更加专用,也更加晦涩的通用函数优异来源是子模块scipy.special,scipy.special中包含了很多的计算函数(包含统计学用到的函数)

可以在官网看到,搜索"gamma function python"

高级的通用函数特性

1. 指定输出

在进行大量运算时,有时候需要指定一个用于存放运算结果的数组是有用的,不同于创建临时数组,可以使用这个特性将计算结果直接写入期望的存储位置

所有的通用函数都可以通过out参数来指定计算结果的存放位置

1 x = np.arange(5)
2 
3 y = np.empty(5)
4 
5 np.multiply(x,10,out=y)
6 Out[138]: array([ 0.,10.,20.,30.,40.])
7 
8 print(y)
9 [ 0. 10. 20. 30. 40.]

这个特性也可以被用作数组视图,例如将计算结果写入指定数组的每隔一个元素位置:

1 y = np.zeros(10)
2 
3 np.power(2,x,out=y[::2])
4 Out[141]: array([ 1.,4.,8.,16.])
5 
6 print(y)
7 [ 1.  0.  2.  0.  4.  0.  8.  0. 16.  0.]

如果这里写的是y[::2] = 2? ** x,那么结果将是创建一个临时数组,该数组存放的是 2 ** x的结果,并且接下来会将这些值复制到y数组中,对于比较小的计算量来说,两种方式差别不大,对于较大数组,通过慎重使用out参数将能够有效节约内存

2.聚合

二元通用函数存在聚合功能,这些聚合可以直接在对象上计算。

例如,使用reduce方法作用一个数组,一个reduce方法会对给定的元素和操作重复执行,直到得到单个结果

举例:

对add通用函数调用reduce方法会返回数组中所有元素的和

1 x = np.arange(1,6)
2 
3 np.add.reduce(x)
4 Out[145]: 15

对multiply通用函数调用reduce方法会返回数组中所有元素的乘积

1 np.multiply.reduce(x)
2 Out[146]: 120

需要存储每次计算的中间结果,可以使用accumulate

1 np.add.accumulate(x)
2 Out[147]: array([ 1,6,15],dtype=int32)
3 
4 np.multiply.accumulate(x)
5 Out[148]: array([  1,24,120],dtype=int32)

还有其他专用函数(np.sum,np.prod,np.cumsum....),也可以实现以上的reduce功能

3.外积

任何通用函数都可以使用outer方法获得两个不同输入数组所有元素对的函数计算结果

意味着可以使用一行代码实现乘法表:

1 x = np.arange(1,6)
2 
3 np.multiply.outer(x,x)
4 Out[150]: 
5 array([[ 1,5],6        [ 2,8,10],7        [ 3,9,12,15],8        [ 4,20],9        [ 5,15,20,25]])

通用函数另一个非常有用的特性是它能操作不同大小和形状的数组,一组这样的操作被称为广播?

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读