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. 生成word附件和word域动态赋值

    生成word文档和word域动态赋值,很多时候需要生成这样的word文档供下载和打印,先制作一个包含了域的 word的模板附件,放在服务器端或者字节流存入数据库,以供需要的时候代码可以获取到,如: 其 ...

  2. JSmpeg-用JavaScript编写的视频播放器

    使用说明:https://github.com/phoboslab/jsmpeg ffmpeg -i rtmp://abc/ccc/111 -f mpegts -codec:v mpeg1video ...

  3. Python3基础 set add 向集合中加入新的元素

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

  4. Python3基础 os.path.getsize 获得文件的大小

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

  5. 【集群搭建】Zookeeper集群环境配置

    1.下载解压安装文件 2.配置文件:conf/zoo.cfg tickTime=2000 dataDir=/usr/sunny/logs/zookeeper/data dataLogDir=/usr/ ...

  6. Wannafly 挑战赛22 D 整数序列 线段树 区间更新,区间查询

    题目链接:https://www.nowcoder.com/acm/contest/160/D 时间限制:C/C++ 2秒,其他语言4秒 空间限制:C/C++ 262144K,其他语言524288K ...

  7. dp问题 -挑战例题 2017-7-24

    01 背包 题意: 在N件物品取出若干件放在容量为W的背包里,每件物品的体积为W1,W2……Wn(Wi为整数),与之相对应的价值为P1,P2……Pn(Pi为整数).求背包能够容纳的最大价值. f[i] ...

  8. C#用Linq查询Combox的数据源

    https://www.cnblogs.com/sufei/archive/2010/01/12/1645763.html var result =  ((DataTable) (this.ComSh ...

  9. Ubuntu上 配置Eclipse:安装CDT

    在最新的 Ubuntu Kylin 16.04 中安装了eclipse,在纠结了很久的网络问题之后,开始了eclipse的配置以便在上面运行ns3. 在官方网站上安装完 eclipse LUNA 之后 ...

  10. python从字符串解析方法名

    方法如下 import requests func_name = 'get' fn_obj = getattr(requests,func_name) fn_obj('http://www.baidu ...