『Numpy』内存分析_numpy结构化数组

三、numpy的结构数组

『Numpy』内存分析_numpy.dtype内存数据解析方式指导

利用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展示的是一个稀疏的结构,但是每一行不会有多余的尾巴,这是因为空元素是由实元素记录偏移量的空隙产生的。

4、view

『Numpy』numpy.ndarray.view_数组视图_reshape、数组切片、数组内存开辟分析

如果两者的itemsize相同,我们可以直接使用array.view(dtype=dtype)来指定数组内存数据的展示视图形式,上面的代码这样修改一下,

def fields_view(arr, fields):
    dtype2 = np.dtype({name:arr.dtype.fields[name] for name in fields})
    return np.ndarray(arr.shape, dtype2, arr, 0, arr.strides)

v = fields_view(a, [‘age‘, ‘height‘])
a.view(dtype=v.dtype)
array([(52,  167.), (44,  170.)],
      dtype={‘names‘:[‘age‘,‘height‘], ‘formats‘:[‘<i4‘,‘<f4‘], ‘offsets‘:[32,40], ‘itemsize‘:44})

当我们最后一个偏移取到行末尾即属性‘height‘时,两者itemsize相等,可以指定view方法解析,

print(v.dtype)
# {‘names‘:[‘age‘,‘height‘], ‘formats‘:[‘<i4‘,‘<f4‘], ‘offsets‘:[32,40], ‘itemsize‘:44}

print(a.dtype)
# {‘names‘:[‘name‘,‘age‘,‘weight‘,‘height‘], ‘formats‘:[‘S30‘,‘<i4‘,‘<f4‘,‘<f4‘], ‘offsets‘:[0,32,36,40], ‘itemsize‘:44, ‘aligned‘:True}

这是因为view本来用于解析内存数据的解析方式,对于结构数组就是每一行的解析方式,这个解析的方式(即输入参数我们自建的dtype)当然必须和内存数据的描述参数(即内存从属的数组的dtype)一致才行,否则解析数据无法对齐。

a.view(dtype=v.dtype)
array([(72,  167.), (64,  170.)],
      dtype={‘names‘:[‘age‘,‘height‘], ‘formats‘:[‘<i4‘,‘<f4‘], ‘offsets‘:[32,40], ‘itemsize‘:44})

原文地址:https://www.cnblogs.com/hellcat/p/8711192.html

时间: 2024-08-02 05:37:21

『Numpy』内存分析_numpy结构化数组的相关文章

『Numpy』内存分析_numpy.dtype内存数据解析方式指导

numpy.dtype用于自定义数据类型,实际是指导python程序存取内存数据时的解析方式. [注意],更改格式不能使用 array.dtype=int32 这样的硬性更改,会不改变内存直接该边解析过程,导致读取出问题,所以使用 array.astype(int32) ,这样才安全. 一.基本使用示例 // 定义一个数据类型,其中name为16为字符串,grades为2个float64的子数组 >>> dt = np.dtype([('name', np.str_, 16), ('gr

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

引.内存探究常用函数 id(),查询对象标识,通常返回的是对象的地址 sys.getsizeof(),返回的是 这个对象所占用的空间大小,对于数组来说,除了数组中每个值占用空间外,数组对象还会存储数组长度.数组类型等其他信息 numpy.ndarray.ctypes.data属性,返回numpy数组的内存位置 array.array.buffer_info(),数组对象的内存信息,返回元素起始地址和元素个数 help(array.buffer_info)'''buffer_info(self,

『Python』内存分析_list和array的内存增长模式

『Python』内存分析_List对象内存占用分析 在Python中,列表是一个动态的指针数组,而array模块所提供的array对象则是保存相同类型的数值的动态数组.由于array直接保存值,因此它所使用的内存比列表少.列表和array都是动态数组,因此往其中添加新元素,而没有空间保存新的元素时,它们会自动重新分配内存块,并将原来的内存中的值复制到新的内存块中.为了减少重新分配内存的次数,通常每次重新分配时,大小都为原来的k倍.k值越大,则重新分配内存的次数越少,但浪费的空间越多.本节通过一系

『Python』内存分析_List对象内存占用分析

『Python』内存分析_下_list和array的内存增长模式 list声明后结构大体分为3部分,变量名称--list对象(结构性数据+指针数组)--list内容,其中id表示的是list对象的位置, v引用变量名称,v[:]引用list对象,此规则对python其他序列结构也成立,以下示范可用id佐证, a=b时,a和b指向同一个list对象 a=b[:]时,a的list对象和b的list对象指向同一个list内容 Q1:元素存储地址是否连续 首先见得的测试一下list对象存储的内容(结构3

Hadoop经典案例Spark实现(七)——日志分析:分析非结构化文件

相关文章推荐 Hadoop经典案例Spark实现(一)--通过采集的气象数据分析每年的最高温度 Hadoop经典案例Spark实现(二)--数据去重问题 Hadoop经典案例Spark实现(三)--数据排序 Hadoop经典案例Spark实现(四)--平均成绩 Hadoop经典案例Spark实现(五)--求最大最小值问题 Hadoop经典案例Spark实现(六)--求最大的K个值并排序 Hadoop经典案例Spark实现(七)--日志分析:分析非结构化文件 1.需求:根据tomcat日志计算ur

『Numpy』常用方法记录

numpy教程 广播机制 numpy计算函数返回默认是一维行向量: import numpy as np a = [[1,1,1], [2,2,2], [3,3,3]] b = (np.sum(a,axis=1)) c = (np.sum(a,axis=0)) print(b,'\n',c) # [3 6 9] # [6 6 6] 所以广播之实际是高维对一维行向量的广播: 除法广播: b = a/(np.sum(a,axis=1)) c = a/(np.sum(a,axis=0)) print(

MaxCompute读取分析OSS非结构化数据的实践经验总结

摘要: 本文背景 很多行业的信息系统中,例如金融行业的信息系统,相当多的数据交互工作是通过传统的文本文件进行交互的.此外,很多系统的业务日志和系统日志由于各种原因并没有进入ELK之类的日志分析系统,也是以文本文件的形式存在的. 1. 本文背景 很多行业的信息系统中,例如金融行业的信息系统,相当多的数据交互工作是通过传统的文本文件进行交互的.此外,很多系统的业务日志和系统日志由于各种原因并没有进入ELK之类的日志分析系统,也是以文本文件的形式存在的.随着数据量的指数级增长,对超大文本文件的分析越来

『计算机视觉』mini深度学习框架实现

一.项目简介 手动实现mini深度学习框架,主要精力不放在运算优化上,仅体会原理. 地址见:miniDeepFrame 相关博客 『TensorFlow』卷积层.池化层详解 『科学计算』全连接层.均方误差.激活函数实现 文件介绍 Layer.py 层 class,已实现:全连接层,卷积层,平均池化层 Loss.py 损失函数 class,已实现:均方误差损失函数 Activate.py 激活函数 class,已实现:sigmoid.tanh.relu test.py 训练测试代码 主流框架对于卷

『Python』Numpy学习指南第三章__常用函数

感觉心情渐渐变好了,加油! np.eye(2)np.savetxt('eye.txt',i2)c,v = np.loadtxt('data.csv', delimiter=',', usecols=(6,7), unpack=True) 1 # __*__coding=utf-8__*__ 2 3 import numpy as np 4 5 # 单位矩阵生成 6 i2 = np.eye(2) 7 print(i2) 8 9 # 保存为txt 10 np.savetxt('eye.txt',i2