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. ELK学习笔记之ElasticSearch的索引详解

    0x00 ElasticSearch的索引和MySQL的索引方式对比 Elasticsearch是通过Lucene的倒排索引技术实现比关系型数据库更快的过滤.特别是它对多条件的过滤支持非常好,比如年龄 ...

  2. 实现multibandblend

           multibandblend是目前图像融和方面比较好的方法.原始论文为<a multivesolution spline with application to image mos ...

  3. 20145317彭垚《网络对抗》Exp6 信息搜集与漏洞扫描

    20145317彭垚<网络对抗>Exp6 信息搜集与漏洞扫描 问题回答 1.哪些组织负责DNS,IP的管理? DNS域名服务器:绝大多数在欧洲和北美洲,中国仅拥有镜像服务器. 全球一共有5 ...

  4. 20165310_java_blog_week1.md

    2165310 <Java程序设计>第1周学习总结 教材学习内容总结 了解Java基本配置环境 学习Java命名.编译.运行规则 拓展学习包的编译.运行 熟悉Git的运用方式 教材学习中的 ...

  5. windows服务与自启动程序的区别(转载)

    转载:http://blog.csdn.net/anddy926/article/details/8464142 在客户端服务器项目实践中,作为服务端必须保持程序的24小时不间断运行,需要做一个监控, ...

  6. 1-20 RHEL7的启动原理和服务控制

    大纲: RHEL7启动原理 RHEL7服务启动配置 网络概述 发布内网服务器 ############################################################ ...

  7. C#学习笔记(十六):索引器和重载运算符

    二维数组如何映射到一维数组 重载运算符 1.算术运算符 2.关系运算符, < 和 > 成对重载 using System; using System.Collections.Generic ...

  8. C# String.Join 与 StringBuilder 对比,谁更快

    String.Join 文档      StringBuilder 文档 这两天刷 Leedcode 做到一道 String 的题时突然想到这俩对比的问题,于是查了一下资料并简单对比了一下. 首先对于 ...

  9. bam/sam格式说明--转载

    在SAM输出的结果中每一行都包括十二项通过Tab分隔,从左到右分别是: 1 序列的名字(Read的名字) 2 概括出一个合适的标记,各个数字分别代表 1     序列是一对序列中的一个 2     比 ...

  10. hdu 3579 Hello Kiki 不互质的中国剩余定理

    Hello Kiki Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Probl ...