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

引、内存探究常用函数

id(),查询对象标识,通常返回的是对象的地址

sys.getsizeof(),返回的是 这个对象所占用的空间大小,对于数组来说,除了数组中每个值占用空间外,数组对象还会存储数组长度、数组类型等其他信息

numpy.ndarray.ctypes.data属性,返回numpy数组的内存位置

array.array.buffer_info(),数组对象的内存信息,返回元素起始地址和元素个数

help(array.buffer_info)
‘‘‘
buffer_info(self, /)
    Return a tuple (address, length) giving the current memory address and the length in items of the buffer
    used to hold array‘s contents.
‘‘‘

 numpy.ndarray.nbytes,获取数组中存储的值的占用空间大小

numpy.ndarray.items,获取数组中每个值的占用空间大小

部分函数试用如下,有意思的是对numpy数组中元素的迭代,它们的id是两个循环出现的地址,原因不明

a = np.array([1,2,3,4,5])

 a.ctypes.data
# 2199487215904

id(a)
# 2199565580288

sys.getsizeof(a)
# 116

a.nbytes
# 20

a.itemsize
# 4

for i in a:
    print(id(i), type(i), i)
# 2199565034888 <class ‘numpy.int32‘> 1
# 2199565034912 <class ‘numpy.int32‘> 2
# 2199565034888 <class ‘numpy.int32‘> 3
# 2199565034912 <class ‘numpy.int32‘> 4
# 2199565034888 <class ‘numpy.int32‘> 5

一、使用array.array和numpy.frombuffer实现动态数组

利用array.array数组对象的内存是确定连续的特性(这也是list为什么不行的原因,实际上array的buffer_info方法就可以查看内存占用情况,返回),使用np访问这块内存,并指定解析方式,从内存创建数组,

从内存创建数组

此时两个对象共用内存,修改数据会影响两者,

import numpy as np
from array import array

a = array(‘d‘, [1,2,3,4])
na = np.frombuffer(a, dtype=np.float)

print(a, na)
na[1] = 20
print(a, na)

array(‘d‘, [1.0, 2.0, 3.0, 4.0]) [ 1. 2. 3. 4.]

array(‘d‘, [1.0, 20.0, 3.0, 4.0]) [ 1. 20. 3. 4.]

多维数组创建以及动态添加元素演示

多维就是一维np.array创建后reshape就行了,

import math
buf = array(‘d‘)
for i in range(5):
    buf.append(math.sin(i*0.1))
    buf.append(math.cos(i*0.1))
data = np.frombuffer(buf, dtype=np.float).reshape(-1,2)
print(data)
[[ 0.          1.        ]
 [ 0.09983342  0.99500417]
 [ 0.19866933  0.98006658]
 [ 0.29552021  0.95533649]
 [ 0.38941834  0.92106099]]

array内存分配机制以及动态数组构建的注意项

import sys

a = array("d")
for i in range(10):
    a.append(i)
    if i == 2:
        na = np.frombuffer(a, dtype=float)
    print(a.buffer_info(), sys.getsizeof(a))
    if i == 4:
        print()
(140269607002576, 1) 96
(140269607002576, 2) 96
(140269607002576, 3) 96
(140269607002576, 4) 96
(140269607286768, 5) 128

(140269607286768, 6) 128
(140269607286768, 7) 128
(140269607286768, 8) 128
(140269607021360, 9) 192
(140269607021360, 10) 192

可以看到初始化后会初始化一段空间,当不够时会继续分配一段新的空间。

numpy数组指针初始化于i=2时,所以并未更新到最新数据,可以看到数据解析的并非我们想要的,

print(na.ctypes.data, ‘\n‘, na)

140269607002576

[ 6.93023941e-310 1.01768729e-316 0.00000000e+000]

二、利用struct结构体实现动态结构数组

利用struct结构体接收行,利用bytearray存储二进制数据,利用frombuffer读取数据,其中使用需要注意数据解析格式的设定要符合struct接收格式设定

import struct

buf = bytearray()
for i in range(5):
    buf += struct.pack(‘=hdd‘,i,math.sin(i*0.1),math.cos(i*0.1))  # ’=‘表示不进行数据内存占用对齐(整形和浮点型占用内存不同)
dtype = np.dtype({‘names‘:[‘id‘,‘sin‘,‘cos‘],‘formats‘:[‘h‘,‘d‘,‘d‘]},align=False)  # align表示是否数据已经进行了对齐
data = np.frombuffer(buf,dtype=dtype)
print(data)
print(data[‘id‘],‘\n‘,data[‘sin‘],‘\n‘,data[‘cos‘])
[(0,  0.        ,  1.        ) (1,  0.09983342,  0.99500417)
 (2,  0.19866933,  0.98006658) (3,  0.29552021,  0.95533649)
 (4,  0.38941834,  0.92106099)]
[0 1 2 3 4]
 [ 0.          0.09983342  0.19866933  0.29552021  0.38941834]
 [ 1.          0.99500417  0.98006658  0.95533649  0.92106099]

此时保存出来的数组类似表格,和pd的DataFrame格式类似,行索引是0~n,列索引既可以是0~m也可以使用names的字段,见下篇。

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

时间: 2024-08-30 03:21:00

『Numpy』内存分析_利用共享内存创建数组的相关文章

『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

内存分析_.Net垃圾回收介绍

垃圾回收 1.       .Net垃圾回收中涉及的名称 1.1.什么是代? 垃圾回收器为了提升性能使用了代的机制,共分为三代(Gen0.Gen1.Gen2).GC工作机制基于以下假设, 1)  对象越新,生存期越短 2)  对象越老,生存期越长 3)  回收堆的一部分比回收整个堆时间短 在应用程序的生命周期中,最近新建的对象被分配在第0代,在一次垃圾回收之后存活下来的进入下一代.这样可以使GC专注于回收最有可能存在更多可回收对象的第0代(最近分配的最有可能很快被释放) 1.2 什么时候发生垃圾

内存分析_.Net内存原理介绍

内存原理介绍 1.       .Net应用程序中的内存 1.1.Net内存类型 Windows使用一个系统:虚拟寻址系统.这个系统的作用是将程序可用的内存地址映射到硬件内存中的实际地址上.其实际结果是在32位的Windows操作系统中,每个进程都可以使用4GB的内存,当然,64位机这个数字就更大了,在这4GB的内存中存储着可执行代码.代码加载的DLL和程序运行的所有变量,这4GB的内存成为虚拟地址空间或虚拟内存.在.Net中要使用多种类型的内存,包括:堆栈.非托管堆和托管堆. C#将数据分为2

『Re』正则表达式模块_常用方法记录

『Re』知识工程作业_主体识别 一个比较完备的正则表达式介绍 几个基础函数 re.compile(pattern, flags=0) 将正则表达式模式编译成一个正则表达式对象,它可以用于匹配使用它的match ()和search ()等方法. 实际有两种使用方式: pattern.匹配方法(string) 或者 re.匹配方法(pattern,string) 使用或|来强化匹配规则: pattern_t = re.compile( '[0-9〇一二三四五六七八九]{4}年.{1,2}月.{1,3

Linux环境编程之共享内存区(一):共享内存区简介

Spark生态圈,也就是BDAS(伯克利数据分析栈),是伯克利APMLab实验室精心打造的,力图在算法(Algorithms).机器(Machines).人(People)之间通过大规模集成,来展现大数据应用的一个平台,其核心引擎就是Spark,其计算基础是弹性分布式数据集,也就是RDD.通过Spark生态圈,AMPLab运用大数据.云计算.通信等各种资源,以及各种灵活的技术方案,对海量不透明的数据进行甄别并转化为有用的信息,以供人们更好的理解世界.Spark生态圈已经涉及到机器学习.数据挖掘.

『TensorFlow』分布式训练_其二_多GPU并行demo分析(待续)

建议比对『MXNet』第七弹_多GPU并行程序设计 models/tutorials/image/cifar10/cifer10_multi_gpu-train.py # Copyright 2015 The TensorFlow Authors. All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file exc

『TensorFlow』迁移学习_他山之石,可以攻玉

目的: 使用google已经训练好的模型,将最后的全连接层修改为我们自己的全连接层,将原有的1000分类分类器修改为我们自己的5分类分类器,利用原有模型的特征提取能力实现我们自己数据对应模型的快速训练.实际中对于一个陌生的数据集,原有模型经过不高的迭代次数即可获得很好的准确率. 实战: 实机文件夹如下,两个压缩文件可以忽略: 花朵图片数据下载: 1 curl -O http://download.tensorflow.org/example_images/flower_photos.tgz 已经

『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(

『TensorFlow』读书笔记_降噪自编码器

『TensorFlow』降噪自编码器设计 之前学习过的代码,又敲了一遍,新的收获也还是有的,因为这次注释写的比较详尽,所以再次记录一下,具体的相关知识查阅之前写的文章即可(见上面链接). # Author : Hellcat # Time : 2017/12/6 import numpy as np import sklearn.preprocessing as prep import tensorflow as tf from tensorflow.examples.tutorials.mni