本文摘自《用Python做科学计算》,版权归原作者所有。

1. NumPy-快速处理数据--ndarray对象--数组的创建和存取

2. NumPy-快速处理数据--ndarray对象--多维数组的存取、结构体数组存取、内存对齐、Numpy内存结构

接下来介绍ufunc运算、广播、ufunc方法

ufunc是universal function的缩写,它是一种能对数组的每个元素进行操作的函数。NumPy内置的许多ufunc函数都是在C语言级别实现的,因此它们的计算速度非常快。

 >>> import numpy as np
>>> x = np.linspace(0, 2*np.pi, 10)#从0到2*PI的等距离的10个数
>>> x
array([ 0. , 0.6981317 , 1.3962634 , 2.0943951 , 2.7925268 ,
3.4906585 , 4.1887902 , 4.88692191, 5.58505361, 6.28318531])
>>> y = np.sin(x)#np.sin是一个ufunc函数,对x中的每个元素求正弦值,然后将结果返回,并且赋值给y
#注意:计算之后x中的值并没有改变,而是新创建了一个数组y保存结果。
>>> y
array([ 0.00000000e+00, 6.42787610e-01, 9.84807753e-01,
8.66025404e-01, 3.42020143e-01, -3.42020143e-01,
-8.66025404e-01, -9.84807753e-01, -6.42787610e-01,
-2.44929360e-16])
>>> t = np.sin(x, x)
#sin(x, x)第二个参数表示计算结果要覆盖的数组,即对x中每个元素求sin,然后结果存放在x中。
>>> x
array([ 0.00000000e+00, 6.42787610e-01, 9.84807753e-01,
8.66025404e-01, 3.42020143e-01, -3.42020143e-01,
-8.66025404e-01, -9.84807753e-01, -6.42787610e-01,
-2.44929360e-16])
>>> id(t) == id(x)#t和x id相同,表示共享一块内存
True

计算sin有两种途径:numpy.sin和math.sin。应当注意的是,math.sin只支持对单个数值求正弦,而numpy.sin既支持单个数值也支持数组。在计算单个数值时,math.sin速度快,而在计算数组时numpy.sin运算速度快。因此在导入numpy时采用import numpy as np的方法,不建议使用*号全部载入,否则后载入的sin会覆盖掉先载入的sin。在使用时根据情况选择使用numpy.sin还是math.sin

此外,numpy.sin返回的数的类型和math.sin返回的类型有所不同,math.sin返回的是Python的标准float类型,而numpy.sin则返回一个numpy.float64类型

 >>> type(math.sin(0.5))# math.sin返回的是Python的标准float类型
<type 'float'>
>>> type(np.sin(0.5)) # numpy.sin则返回一个numpy.float64类型
<type 'numpy.float64'>

add()函数:计算两个数组相加

>>> a = np.arange(0, 4)
>>> a
array([0, 1, 2, 3])
>>> b = np.arange(1, 5)
>>> b
array([1, 2, 3, 4])
>>> np.add(a, b) #数组a + b带返回结果
array([1, 3, 5, 7])
>>> np.add(a, b, a)#第三个参数用来存放计算结果
array([1, 3, 5, 7])
>>> a
array([1, 3, 5, 7])

由于Python的操作符重载功能,计算两个数组相加可以简单地写为a+b,而np.add(a,b,a)则可以用a+=b来表示。下面是数组的运算符和其对应的ufunc函数的一个列表,注意除号"/"的意义根据是否激活__future__.division有所不同。

y = x1 + x2 add(x1, x2 [, y])
y = x1 - x2 subtract(x1, x2 [, y])
y = x1 * x2 multiply (x1, x2 [, y])
y = x1 / x2 divide (x1, x2 [, y]), 如果两个数组的元素为整数,那么用整数除法
y = x1 / x2 true divide (x1, x2 [, y]), 总是返回精确的商
y = x1 // x2 floor divide (x1, x2 [, y]), 总是对返回值取整
y = -x negative(x [,y])
y = x1 ** x2 power(x1, x2 [, y])
y = x1 % x2 remainder(x1, x2 [, y]), mod(x1, x2, [, y])

数组对象支持这些操作符,极大地简化了算式的编写。

广播

当我们使用ufunc函数对两个数组进行计算时,ufunc函数会对这两个数组的对应元素进行计算,因此它要求这两个数组有相同的大小(shape相同)。如果两个数组的shape不同的话,会进行如下的广播(broadcasting)处理:

  1. 让所有输入数组都向其中shape最长的数组看齐,shape中不足的部分都通过在前面加1补齐
  2. 输出数组的shape是输入数组shape的各个轴上的最大值
  3. 如果输入数组的某个轴和输出数组的对应轴的长度相同或者其长度为1时,这个数组能够用来计算,否则出错
  4. 当输入数组的某个轴的长度为1时,沿着此轴运算时都用此轴上的第一组值
 >>> a = np.arange(0, 60, 10).reshape(-1, 1)#产生0~60,间距为10的数组,行(第0轴)为-1则根据列自动匹配
>>> a
array([[ 0],
[10],
[20],
[30],
[40],
[50]])
>>> a.shape#a是二维数组
(6, 1)
>>> b = np.arange(0, 5)
>>> b
array([0, 1, 2, 3, 4])
>>> b.shape#b是一维数组
(5,)
>>> c = a + b
#由于a和b的shape长度(也就是ndim属性)不同,根据规则1,需要让b的shape向a对齐,于是将b的shape补齐为(1,5)。
#两个输入数组的shape分别为(6,1)和(1,5),根据规则2,可知输出数组的shape为(6,5)。
#规则3,当输入数组的某个轴的长度为1时,沿着此轴运算时都用此轴上的第一组值。
>>> c
array([[ 0, 1, 2, 3, 4],
[10, 11, 12, 13, 14],
[20, 21, 22, 23, 24],
[30, 31, 32, 33, 34],
[40, 41, 42, 43, 44],
[50, 51, 52, 53, 54]])
>>> c.shape
(6, 5)

由于这种广播计算很常用,因此numpy提供了一个快速产生如上面a,b数组的方法: ogrid对象:

ogrid是一个很有趣的对象,它像一个多维数组一样,用切片组元作为下标进行存取,返回的是一组可以用来广播计算的数组。其切片下标有两种形式:

  • 开始值:结束值:步长,和np.arange(开始值, 结束值, 步长)类似

  • 开始值:结束值:长度j,当第三个参数为虚数时,它表示返回的数组的长度,和np.linspace(开始值, 结束值, 长度)类似:
 >>> x,y = np.ogrid[0:5,0:5]        #开始值:结束值:步长
>>> x
array([[0],
[1],
[2],
[3],
[4]])
>>> y
array([[0, 1, 2, 3, 4]])
>>> x, y = np.ogrid[0:1:4j, 0:1:3j]#开始值:结束值:长度j
>>> x
array([[ 0. ],
[ 0.33333333],
[ 0.66666667],
[ 1. ]])
>>> y
array([[ 0. , 0.5, 1. ]])

注意:ogrid不是函数!!!

根据Python的语法,只有在中括号中才能使用用冒号隔开的切片语法,如果ogrid是函数的话,那么这些切片必须使用slice函数创建,这显然会增加代码的长度。

ufunc的方法

ufunc函数本身还有些方法,这些方法只对两个输入一个输出(如加法)的ufunc函数有效,其它的ufunc对象调用这些方法时会抛出ValueError异常。

reduce 方法和Python的reduce函数类似,语法为:

 <op>.reduce (array=, axis=0, dtype=None)
#沿着axis轴对array进行操作,将<op>运算符插入到沿axis轴的所有子数组或者元素当中
 >>> np.add.reduce([1,2,3]) # 1 + 2 + 3
6
>>> np.add.reduce([[1,2,3],[4,5,6]], axis=1) # 1,4 + 2,5 + 3,6
array([ 6, 15])

accumulate 方法和reduce方法类似,只是它返回的数组和输入的数组的shape相同,保存所有的中间计算结果:

 >>> np.add.accumulate([1,2,3])
array([1, 3, 6])
>>> np.add.accumulate([[1,2,3],[4,5,6]], axis=1)
array([[ 1, 3, 6],
[ 4, 9, 15]])

reduceat 方法计算多组reduce的结果,通过indices参数指定一系列reduce的起始和终了位置。

 >>> a = np.array([1,2,3,4])
>>> result = np.add.reduceat(a,indices=[0,1,0,2,0,3,0])
>>> result
array([ 1, 2, 3, 3, 6, 4, 10])

outer 方法,<op>.outer(a,b)方法的计算等同于如下程序:

 >>> np.multiply.outer([1,2,3,4,5],[2,3,4])#乘法表最终是通过广播的方式计算出来的
array([[ 2, 3, 4],
[ 4, 6, 8],
[ 6, 9, 12],
[ 8, 12, 16],
[10, 15, 20]])
#>>> np.multiply([1,2,3,4,5],[2,3,4])#ValueError

NumPy-快速处理数据--ufunc运算--广播--ufunc方法的更多相关文章

  1. Python科学计算:用NumPy快速处理数据

    创建数组 import numpy as np a=np.array([1,2,3]) b=np.array([[1,2,3],[4,5,6],[7,8,9]]) b[1,1]=10 print(a. ...

  2. Python科学计算学习一 NumPy 快速处理数据

    1 创建数组 (1) array(boject, dtype=None, copy=True, order=None, subok=False, ndmin=0) a = array([1, 2, 3 ...

  3. Numpy 中一维数据转置的几种方法

    把一个一维数组转置有如下几种方法.就是把 一行 n列的数组 转换成 n 行一列的数组, 如 如 [1,2,3,4] => [[1] [2]  [3] [4]] 方法一: np.transpose ...

  4. 『Numpy』高级函数_np.nditer()&ufunc运算

    1.np.nditer():numpy迭代器 默认情况下,nditer将视待迭代遍历的数组为只读对象(read-only),为了在遍历数组的同时,实现对数组元素值得修改,必须指定op_flags=[' ...

  5. Numpy:ndarray数据类型和运算

    Numpy的ndarray:一种多维数组对象 N维数组对象,该对象是一个快速而灵活的大数据集容器,nadarry是一个通用的同构数据多维容器,也就是说,其中的所有元素必须是相同类型的.每个数组都有一个 ...

  6. Numpy数值类型与数值运算-03

    什么是NumPy? NumPy是Python中科学计算的基本软件包.它是一个Python库,提供多维数组对象,各种派生对象(例如蒙版数组和矩阵) 以及各种例程,用于对数组进行快速操作,包括数学,逻辑, ...

  7. numpy快速入门

    numpy快速入门 numpy是python的科学计算的核心库,很多更高层次的库都基于numpy.博主不太喜欢重量级的MATLAB,于是用numpy进行科学计算成为了不二选择. 本文主要参考Scipy ...

  8. 洛谷 P1226 【模板】快速幂||取余运算

    题目链接 https://www.luogu.org/problemnew/show/P1226 题目描述 输入b,p,k的值,求b^p mod k的值.其中b,p,k*k为长整型数. 输入输出格式 ...

  9. 二分求幂/快速幂取模运算——root(N,k)

    二分求幂 int getMi(int a,int b) { ; ) { //当二进制位k位为1时,需要累乘a的2^k次方,然后用ans保存 == ) { ans *= a; } a *= a; b / ...

随机推荐

  1. [WinForm]Dundas Chart控件学习(附源码)

    1.Dundas公司简介 加拿大的一家公司,专业做图表展现的,很牛,据说现在被Microsoft收购了.官网地址:http://www.dundas.com/ 2.Chart基本要素 3.最简单的柱状 ...

  2. SpringXML方式配置bean的自动装配autowire

    Spring的自动装配,也就是定义bean的时候让spring自动帮你匹配到所需的bean,而不需要我们自己指定了. 例如: User实体类里面有一个属性role 1 2 3 4 5 6 7 publ ...

  3. C++(笔记)浅析vector容器的实例

    http://www.runoob.com/w3cnote/cpp-vector-container-analysis.html 转载请注明出处 浅然的专栏 https://blog.csdn.net ...

  4. 《Effective C++》第4章 设计与声明(1)-读书笔记

    章节回顾: <Effective C++>第1章 让自己习惯C++-读书笔记 <Effective C++>第2章 构造/析构/赋值运算(1)-读书笔记 <Effecti ...

  5. 201621123006 《Java程序设计》第2周学习总结

    1. 本周学习总结 以几个关键词描述本周的学习内容.并将关键词之间的联系描述或绘制出来. 原则:少而精,自己写.即使不超过5行也可,但请一定不要简单的复制粘贴. java数据类型:java数据类型分为 ...

  6. bfs+状态压缩dp

    题目连接 题解 : 对两两管道进行bfs,然后用dp[i][j] 来表示在i状态下通过了前j个管道 参考博客 #include<bits/stdc++.h> using namespace ...

  7. Linux:cd命令详解

    cd 用来变更用户所在目录的 绝对路径:路径的写法一定由根目录 "/" 写起.例如 /usr/local/mysql 这就是绝对路径.相对路径:路径的写法不是由根目录 " ...

  8. WIN7不能上网

    http://zhidao.baidu.com/link?url=lYL0Sti_nX3JDz3pA3cVh49nyYDEQBJ6P5fxwB4La0FurHlgmWGMdgfMGjQSWxj17sH ...

  9. (二) ffmpeg filter学习--混音实现

    Audio 混音实现 从FFMPEG原生代码doc/examples/filtering_audio.c修改而来. ffmpeg版本信息 ffmpeg version N-82997-g557c0df ...

  10. [Linux] Boot分区满了的处理方法 The volume "boot" has only 0 bytes disk space remaining

    1.查看系统目前正在用的内核 abby@abby:~$ uname -r ..--generic 2.查看/boot保存的所有内核 abby@abby:~$ ls -lah /boot total 3 ...