1、np.nditer():numpy迭代器

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

np.nditer(a, op_flags=['readwrite'])

基本迭代参数flag=['f_index'/'mulit_index'],可输出自身坐标it.index/it.multi_index:

a = np.arange(6).reshape(2,3)

'''迭代方式'''

# 单维迭代
it = np.nditer(a, flags=['f_index'])
while not it.finished:
print("%d <%s>" % (it[0], it.index))
it.iternext() #0 <0>
#1 <2>
#2 <4>
#3 <1>
#4 <3>
#5 <5> # 多维迭代
it = np.nditer(a, flags=['multi_index'])
while not it.finished:
print("%d <%s>" % (it[0], it.multi_index))
it.iternext() #0 <(0, 0)>
#1 <(0, 1)>
#2 <(0, 2)>
#3 <(1, 0)>
#4 <(1, 1)>
#5 <(1, 2)>

改变迭代的顺序:

# 列顺序迭代
it = np.nditer(a, flags=['f_index'], order='F')
while not it.finished:
print("%d <%s>" % (it[0], it.index), end=' | ')
it.iternext() # 0 <0> | 3 <1> | 1 <2> | 4 <3> | 2 <4> | 5 <5> | # 行顺序迭代
it = np.nditer(a, flags=['f_index'], order='C')
while not it.finished:
print("%d <%s>" % (it[0], it.index), end=' | ')
it.iternext() # 0 <0> | 1 <2> | 2 <4> | 3 <1> | 4 <3> | 5 <5> |

2、ufunc运算

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

通过组合标准的ufunc函数的调用,可以实现各种算式的数组计算。不过有些时候这种算式不易编写,而针对每个元素的计算函数却很容易用Python实现,这时可以用frompyfunc函数将一个计算单个元素的函数转换成ufunc函数。这样就可以方便地用所产生的ufunc函数对数组进行计算了。让我们来看一个例子。

我们想用一个分段函数描述三角波,三角波的样子如下图所示:

三角波可以用分段函数进行计算

我们很容易根据上图所示写出如下的计算三角波某点y坐标的函数:

def triangle_wave(x, c, c0, hc):
x = x - int(x) # 三角波的周期为1,因此只取x坐标的小数部分进行计算
if x >= c: r = 0.0
elif x < c0: r = x / c0 * hc
else: r = (c-x) / (c-c0) * hc
return r

显然triangle_wave函数只能计算单个数值,不能对数组直接进行处理。我们可以用下面的方法先使用列表包容(List comprehension),计算出一个list,然后用array函数将列表转换为数组:

x = np.linspace(0, 2, 1000)
y = np.array([triangle_wave(t, 0.6, 0.4, 1.0) for t in x])

这种做法每次都需要使用列表包容语法调用函数,对于多维数组是很麻烦的。让我们来看看如何用frompyfunc函数来解决这个问题:

triangle_ufunc = np.frompyfunc( lambda x: triangle_wave(x, 0.6, 0.4, 1.0), 1, 1)
y2 = triangle_ufunc(x)

frompyfunc的调用格式为frompyfunc(func, nin, nout),其中func是计算单个元素的函数,nin是此函数的输入参数的个数,nout是此函数的返回值的个数。虽然triangle_wave函数有4个参数,但是由于后三个c, c0, hc在整个计算中值都是固定的,因此所产生的ufunc函数其实只有一个参数。为了满足这个条件,我们用一个lambda函数对triangle_wave的参数进行一次包装。这样传入frompyfunc的函数就只有一个参数了。这样子做,效率并不是太高,另外还有一种方法:

def triangle_func(c, c0, hc):
def trifunc(x):
x = x - int(x) # 三角波的周期为1,因此只取x坐标的小数部分进行计算
if x >= c: r = 0.0
elif x < c0: r = x / c0 * hc
else: r = (c-x) / (c-c0) * hc
return r # 用trifunc函数创建一个ufunc函数,可以直接对数组进行计算, 不过通过此函数
# 计算得到的是一个Object数组,需要进行类型转换
return np.frompyfunc(trifunc, 1, 1) y2 = triangle_func(0.6, 0.4, 1.0)(x)

我们通过函数triangle_func包装三角波的三个参数,在其内部定义一个计算三角波的函数trifunc,trifunc函数在调用时会采用triangle_func的参数进行计算。最后triangle_func返回用frompyfunc转换结果。

值得注意的是用frompyfunc得到的函数计算出的数组元素的类型为object,因为frompyfunc函数无法保证Python函数返回的数据类型都完全一致。因此还需要再次 y2.astype(np.float64)将其转换为双精度浮点数组。

『Numpy』高级函数_np.nditer()&ufunc运算的更多相关文章

  1. 『Numpy』内存分析_高级切片和内存数据解析

    在计算机中,没有任何数据类型是固定的,完全取决于如何看待这片数据的内存区域. 在numpy.ndarray.view中,提供对内存区域不同的切割方式,来完成数据类型的转换,而无须要对数据进行额外的co ...

  2. 『Numpy』常用方法记录

    numpy教程 防止输出省略号 import numpy as np np.set_printoptions(threshold=np.inf) 广播机制 numpy计算函数返回默认是一维行向量: i ...

  3. 『Numpy』内存分析_利用共享内存创建数组

    引.内存探究常用函数 id(),查询对象标识,通常返回的是对象的地址 sys.getsizeof(),返回的是 这个对象所占用的空间大小,对于数组来说,除了数组中每个值占用空间外,数组对象还会存储数组 ...

  4. 『Numpy』内存分析_numpy.dtype解析内存数据

    numpy.dtype用于自定义数据类型,实际是指导python程序存取内存数据时的解析方式. [注意],更改格式不能使用 array.dtype=int32 这样的硬性更改,会不改变内存直接该边解析 ...

  5. 『TensorFlow』高级高维切片gather_nd

    gather用于高级切片,有关官方文档的介绍,关于维度的说明很是费解,示例也不太直观,这里给出我的解读,示例见下面,     indices = [[0, 0], [1, 1]]    params ...

  6. 『Numpy』np.ravel()和np.flatten()

    What is the difference between flatten and ravel functions in numpy? 两者的功能是一致的,将多维数组降为一维,但是两者的区别是返回拷 ...

  7. 『C++』Temp_2018_12_13 函数指针

    #include <iostream> #include <string> using namespace std; class Test{ private: string n ...

  8. 『Numpy』np.meshgrid

    生成网格坐标,一个很好的说明图如下: 虽然xy双坐标比较常用,但实际上其输入可以是任意多的数组,输出数组数目等于输出数组数目,且彼此间shape一致. 如果输入数组不是一维的,会拉伸为1维进行计算. ...

  9. 『计算机视觉』Mask-RCNN_锚框生成

    Github地址:Mask_RCNN 『计算机视觉』Mask-RCNN_论文学习 『计算机视觉』Mask-RCNN_项目文档翻译 『计算机视觉』Mask-RCNN_推断网络其一:总览 『计算机视觉』M ...

随机推荐

  1. jsonp 方式处理跨域前后端代码如何配合?

    JSONP(JSON with Padding)(json   数据填充)只支持GET请求 是JSON的一种“使用模式”,可用于解决主流浏览器的跨域数据访问的问题. 跨域产生原因是浏览器的同源策略.( ...

  2. Linux基础命令---bc

    bc bc是一种算数语言,其语法和c语言类似,可以交互执行.通过命令行选项可以获得一个标准的数学库.如果请求,在处理任何文件之前定义数学库.BC从处理所有文件的代码开始.命令行中列出的文件按所列顺序排 ...

  3. redis 主从同步搭建

    redis 一主二从 1.redis 安装 安装教程:https://www.cnblogs.com/zwcry/p/9505949.html 2.redis主从 1)创建主从目录 mkdir /us ...

  4. php随笔10-thinkphp 3.1.3 模板继承 布局

    8.25 模板继承 模 板继承是3.1.2版本添加的一项更加灵活的模板布局方式,模板继承不同于模板布局,甚至来说,应该在模板布局的上层.模板继承其实并不难理解,就好比类 的继承一样,模板也可以定义一个 ...

  5. C/C++笔记 #035# Makefile

    相关资料: Understanding roles of CMake, make and GCC GCC and Make ( A simple tutorial, teaches u how to ...

  6. Python Web学习笔记之图解TCP/IP协议和浅析算法

    本文通过两个图来梳理TCP-IP协议相关知识.TCP通信过程包括三个步骤:建立TCP连接通道,传输数据,断开TCP连接通道.如图1所示,给出了TCP通信过程的示意图. 图1主要包括三部分:建立连接.传 ...

  7. Python入门之Pycharm开发中最常用快捷键

    要查阅Pycharm的快捷键,当然要看官方文档,https://www.jetbrains.com/help/pycharm/mastering-keyboard-shortcuts.html 编辑类 ...

  8. laravel 对接支付宝

    使用的库 omnipay-alipay 申请支付宝支付 这个就不说了, 不明白如何下手的伙伴让运营去和支付宝客服联系吧 composer 安装git库 将以下代码添加到 composer.json { ...

  9. Python3基础 list 推导式 生成100以内的偶数列表

             Python : 3.7.0          OS : Ubuntu 18.04.1 LTS         IDE : PyCharm 2018.2.4       Conda ...

  10. 骁龙820和KryoCPU:异构计算与定制计算的作用 【转】

    本文转载自:https://www.douban.com/group/topic/89037625/ Qualcomm骁龙820处理器专为提供创新用户体验的顶级移动终端而设计.为实现消费者所期望的创新 ...