『Numpy』内存分析_高级切片和内存数据解析
import numpy as np
x = np.arange(10, dtype=np.int) print('An integer array:', x)
print ('An float array:', x.view(np.float))
An integer array: [0 1 2 3 4 5 6 7 8 9]An float array:[ 0.00000000e+000 4.94065646e-324
9.88131292e-324 1.48219694e-323 1.97626258e-323
2.47032823e-323 2.96439388e-323 3.45845952e-323
3.95252517e-323 4.44659081e-323]
在实际使用中我们往往会采取更复杂的dtype(也就是说view可以与dtype搭配使用)输出内存中的值,后面我们会示范对于结构化数组的较为复杂的view使用。
一、view和copy
我们从numpy.reshape()函数入手,文档对于其返回值的解释:
Returns
-------
reshaped_array : ndarray
This will be a new view object if possible; otherwise, it will
be a copy. Note there is no guarantee of the *memory layout* (C- or
Fortran- contiguous) of the returned array.
a = np.zeros([2,10], dtype=np.int32)
b = a.T # 转置破坏连续结构 a.flags['C_CONTIGUOUS'] # True
b.flags['C_CONTIGUOUS'] # False np.may_share_memory(a,b) # True
b.base is a # True
id(b)==id(a) # False a.shape = 20 # a的shape变了
a.flags['C_CONTIGUOUS'] # True # b.shape = 20
# AttributeError: incompatible shape for a non-contiguous array
# 想要使用指定shape的方式,只能是连续数组,但是reshape方法由于不改变原数组,所以reshape不受影响
数组切片是否会copy数据?
不过,数组的切片对象虽然并非contiguous,但是对它的reshape操作并不会copy新的对象,
a = np.arange(16).reshape(4,4) print(a.T.flags['C_CONTIGUOUS'],a[:,0].flags['C_CONTIGUOUS'])
# False False print (np.may_share_memory(a,a.T.reshape(16)),
np.may_share_memory(a,a[:,0].reshape(4)))
# False True
但是,下一小节会介绍,高级切片会copy数组,开辟新的内存。
二、numpy的结构数组
利用np.dtype可以构建结构数组,numpy.ndarray.base会返回内存主人的信息,文档如下,
Help on getset descriptor numpy.ndarray.base:
base
Base object if memory is from some other object.
Examples
--------
The base of an array that owns its memory is None:
>>> x = np.array([1,2,3,4])
>>> x.base is None
True
Slicing creates a view, whose memory is shared with x:
>>> y = x[2:]
>>> y.base is x
True
1、建立结构数组
persontype = np.dtype({
'names':['name','age','weight','height'],
'formats':['S30','i','f','f']}, align=True)
a = np.array([('Zhang',32,72.5,167),
('Wang',24,65,170)],dtype=persontype)
a['age'].base
array([(b'Zhang', 32, 72.5, 167.),
(b'Wang', 24, 65. , 170.)],
dtype={'names':['name','age','weight','height'],
'formats':['S30','<i4','<f4','<f4'],
'offsets':[0,32,36,40],
'itemsize':44,
'aligned':True})
2、高级切片和普通切片的不同
In [26]: a.base
In [27]: a[0].base
In [28]: a[:1].base
Out[28]: array([123, 4, 5, 6, 78])
In [29]: a[[0,1]].base In [30]: a.base is None
Out[30]: True
In [31]: a[0].base is None
Out[31]: True
In [32]: a[:1].base is None
Out[32]: False
In [33]: a[[0,1]].base is None
Out[33]: True
由上可见高级切片会开辟新的内存,复制被切出的数据,这是因为这种不规则的内存访问使用原来的内存结构效率很低(逻辑相邻元素内存不相邻,标准的访问由于固定了起始和步长相当于访问相邻元素,所以效率较高),拷贝出来就是连续的内存数组了。
3、高级切片且不开辟新内存的方法
回到上上小节的结构数组,
print(a['age'].base is a)
print(a[['age', 'height']].base is None)
True
True
我们通过指定内存解析方式,实现不开辟新内存,将原内存解析为高级切片指定的结构数组,
def fields_view(arr, fields):
dtype2 = np.dtype({name:arr.dtype.fields[name] for name in fields})
# print(dtype2)
# {'names':['age','weight'], 'formats':['<i4','<f4'], 'offsets':[32,36], 'itemsize':40}
# print([(name,arr.dtype.fields[name]) for name in fields])
# [('age', (dtype('int32'), 32)), ('weight', (dtype('float32'), 36))]
# print(arr.strides)
# (44,)
return np.ndarray(arr.shape, dtype2, arr, 0, arr.strides)
'''
ndarray(shape, dtype=float, buffer=None, offset=0,
| strides=None, order=None) 参数 类型 作用
shape int型tuple 多维数组的形状
dtype data-type 数组中元素的类型
buffer 用于初始化数组的buffer
offset int buffer中用于初始化数组的首个数据的偏移
strides int型tuple 每个轴的下标增加1时,数据指针在内存中增加的字节数
order 'C' 或者 'F' 'C':行优先;'F':列优先
''' v = fields_view(a, ['age', 'weight'])
print(v.base is a) v['age'] += 10
print('+++'*10)
print(v)
print(v.dtype)
print(v.dtype.fields)
print('+++'*10)
print(a)
print(a.dtype)
print(a.dtype.fields)
True
++++++++++++++++++++++++++++++
[(42, 72.5) (34, 65. )]
{'names':['age','weight'], 'formats':['<i4','<f4'], 'offsets':[32,36], 'itemsize':40}
{'age': (dtype('int32'), 32), 'weight': (dtype('float32'), 36)}
++++++++++++++++++++++++++++++
[(b'Zhang', 42, 72.5, 167.) (b'Wang', 34, 65. , 170.)]
{'names':['name','age','weight','height'], 'formats':['S30','<i4','<f4','<f4'], 'offsets':[0,32,36,40], 'itemsize':44, 'aligned':True}
{'name': (dtype('S30'), 0), 'age': (dtype('int32'), 32), 'weight': (dtype('float32'), 36), 'height': (dtype('float32'), 40)}
这里注意一下.dtype的’itemsize‘参数,表示添加一条(行)数据,内存增加了多少字节,由于保存了'offsets'偏移信息,我们生成的dtype展示的是一个稀疏的结构,但是每一行不会有多余的尾巴,这是因为空元素是由实元素记录偏移量的空隙产生的。
在『Numpy』内存分析_numpy.dtype解析内存数据中我们会更详细的介绍有关数组内存解析的方法。
『Numpy』内存分析_高级切片和内存数据解析的更多相关文章
- 『TensorFlow』分布式训练_其三_多机分布式
本节中的代码大量使用『TensorFlow』分布式训练_其一_逻辑梳理中介绍的概念,是成熟的多机分布式训练样例 一.基本概念 Cluster.Job.task概念:三者可以简单的看成是层次关系,tas ...
- 『Re』正则表达式模块_常用方法记录
『Re』知识工程作业_主体识别 一个比较完备的正则表达式介绍 几个基础函数 re.compile(pattern, flags=0) 将正则表达式模式编译成一个正则表达式对象,它可以用于匹配使用它的m ...
- 『Numpy』内存分析_利用共享内存创建数组
引.内存探究常用函数 id(),查询对象标识,通常返回的是对象的地址 sys.getsizeof(),返回的是 这个对象所占用的空间大小,对于数组来说,除了数组中每个值占用空间外,数组对象还会存储数组 ...
- 『Numpy』常用方法记录
numpy教程 防止输出省略号 import numpy as np np.set_printoptions(threshold=np.inf) 广播机制 numpy计算函数返回默认是一维行向量: i ...
- 『TensorFlow』分布式训练_其二_单机多GPU并行&GPU模式设定
建议比对『MXNet』第七弹_多GPU并行程序设计 一.tensorflow GPU设置 GPU指定占用 gpu_options = tf.GPUOptions(per_process_gpu_mem ...
- 『TensorFlow』读书笔记_降噪自编码器
『TensorFlow』降噪自编码器设计 之前学习过的代码,又敲了一遍,新的收获也还是有的,因为这次注释写的比较详尽,所以再次记录一下,具体的相关知识查阅之前写的文章即可(见上面链接). # Aut ...
- 『PyTorch』第九弹_前馈网络简化写法
『PyTorch』第四弹_通过LeNet初识pytorch神经网络_上 『PyTorch』第四弹_通过LeNet初识pytorch神经网络_下 在前面的例子中,基本上都是将每一层的输出直接作为下一层的 ...
- 内存分析_.Net垃圾回收介绍
垃圾回收 1. .Net垃圾回收中涉及的名称 1.1.什么是代? 垃圾回收器为了提升性能使用了代的机制,共分为三代(Gen0.Gen1.Gen2).GC工作机制基于以下假设, 1) 对象 ...
- 内存分析_.Net内存原理介绍
内存原理介绍 1. .Net应用程序中的内存 1.1.Net内存类型 Windows使用一个系统:虚拟寻址系统.这个系统的作用是将程序可用的内存地址映射到硬件内存中的实际地址上.其实际结果 ...
随机推荐
- 20165317Java实验五 网络编程与安全
实验五 网络编程与安全 一.中缀转后缀 参考http://www.cnblogs.com/rocedu/p/6766748.html#SECDSA 结对实现中缀表达式转后缀表达式的功能 MyBC.ja ...
- Elasticsearch学习笔记(四)ElasticSearch分布式机制
一.Elasticsearch对复杂分布式机制透明的隐藏特性 1.分片机制: (1)index包含多个shard,每个shard都是一个最小工作单元,承载部分数据,lucene实例,完整的建立索引和处 ...
- Spark入门到精通--(第一节)Spark的前世今生
最近由于公司慢慢往spark方面开始转型,本人也开始学习,今后陆续会更新一些spark学习的新的体会,希望能够和大家一起分享和进步. Spark是什么? Apache Spark™ is a fast ...
- 43-2-CAN协议
1.帧的种类 通信是通过以下 5 种类型的帧进行的. • 数据帧 • 遥控帧 • 错误帧 • 过载帧 • 帧间隔 另外, 数据帧和遥控帧有标准格式和扩展格式两种格式.标准格式有 11 个位的标识符(I ...
- SharePoint 命令行
网站集备份: Backup-SPSite http://sp2013 -Path C:\sp.bak 网站集还原: Restore-SPSite http://sp2013/sites/dyzx -P ...
- MySql 创建索引原则
https://blog.csdn.net/csdnones/article/details/50412603 为了使索引的使用效率更高,在创建索引时,必须考虑在哪些字段上创建索引和创建什么类型的索引 ...
- Tomcat不加项目名称访问设置
一.Tomcat不加项目名称访问设置 一.方法一:修改配置文件server.xml 1.修改配置文件server.xml <Host appBase="webapps" au ...
- Git换行符是如何精确控制的
Git换行符是如何精确控制的 Checkout Windows-style, commit Unix-style Git will convert LF to CRLF when checking o ...
- 4.Python3运算符
4.1算数运算符(以下假设变量a为10,变量b为21) 实例操作: print(3 + 5) #数字3与5相加 print(3 - 5) #数字3与5相减 print(3 * 5) #数字3与5相乘 ...
- 【css】适配iphoneX
/*适配iphoneX*/ @media only screen and (device-width: 375px) and (device-height: 812px) and (-webkit-d ...