您当前所在位置:首页攻略Python中Numpy数组的紧凑二进制存储与内存映射读取

Python中Numpy数组的紧凑二进制存储与内存映射读取

更新:2024-09-10 09:57:31编辑:游戏资讯归类:攻略

在数据存储过程中,通常会选择使用明文形式存储数据,如json、txt、csv等。对于需要较高压缩率的存储格式,可以选择hdf5或npz等格式。此外,还有一种相当紧凑的数据存储格式,即直接按照二进制格式存储。在这种格式下,存储的数据之间没有间隔符,在没有压缩的情况下,这应该是体积最小的存储类型。

在Python中,可以使用numpy.tofile()功能,将numpy数组类型直接存储到二进制文件中。在读取时,虽然可以使用open(file_name, 'rb')进行读取,但为了适配大量IO的场景,可以使用内存映射mmap的形式来进行数据读取。

以下是一个完整的示例代码,相关的功能直接用注释的形式在代码中标记:

import numpy as np
import mmap
import resource
# 获取页数据量大小(单位:字节)
PAGE_SIZE = resource.getpagesize()
# 定义单精度浮点数数据占用字节(单位:字节)
DATA_SIZE = 4
# 计算页存储数据数量(num_float32)
PAGE_FNUM = int(PAGE_SIZE/DATA_SIZE)
print ("The PAGE_SIZE is: {}".format(PAGE_SIZE))
print ("Corresponding float32 numbers should be: {}".format(PAGE_FNUM))
# 生成示例数据,使用PAGE_FNUM+4大小的数据量定义两页数据
tmp_arr = np.arange(PAGE_FNUM+4).astype(np.float32)
# 数据存储路径
tmp_file = '/tmp/tmp.dat'
# 将数组存储到二进制文件中
tmp_arr.tofile(tmp_file)
# 每次从二进制文件中读取4个数据
READ_NUM = 4
with open(tmp_file, 'rb') as file:
    # 第一页数据的内存映射
    mm = mmap.mmap(file.fileno(), 0, access=mmap.ACCESS_READ, offset=0)
    # 第一页数据的1、2、3、4位数据
    print (np.frombuffer(mm.read(DATA_SIZE*READ_NUM), dtype='<f4'))
    # 第一页数据的5、6、7、8位数据
    print (np.frombuffer(mm.read(DATA_SIZE*READ_NUM), dtype='<f4'))
    # 第二页数据的内存映射
    mm = mmap.mmap(file.fileno(), 0, access=mmap.ACCESS_READ, offset=PAGE_SIZE)
    # 第二页数据的1~4位数据
    print (np.frombuffer(mm.read(DATA_SIZE*READ_NUM), dtype='<f4'))
    # 第二页数据的5~8位数据
    print (np.frombuffer(mm.read(DATA_SIZE*READ_NUM), dtype='<f4'))
    # 关闭内存映射
    mm.close()
# 退出文件IO

该脚本的输出结果为:

The PAGE_SIZE is: 4096
Corresponding float32 numbers should be: 1024
[0. 1. 2. 3.]
[4. 5. 6. 7.]
[1024. 1025. 1026. 1027.]
[]

我们打印的第一个数据是页大小,这里显示是4096个字节。而一个单精度浮点数占4个字节,所以一页存了1024个单精度浮点数,也就是第二个打印输出的结果。由于我们定义的numpy数组是一个从0开始的递增数组,因此第一页数据的前8位数字就是从0到7。而第二页的数据是1024~1027一共4个浮点数,占16个字节。所以我们在第二页第二次使用numpy.frombuffer()去读取数据的时候,得到的是一个空的数组。此外我们可以查看一下这个二进制文件的大小:

In [1]: import os

In [2]: os.path.getsize('/tmp/tmp.dat')
Out[2]: 4112

一共是4112个字节,刚好是4096+16个字节。

本文介绍了一种在Python中将Numpy数组转存为一个紧凑的二进制格式的文件,以及使用内存映射的形式进行读取的方案。一个二进制的数据流,不仅可以更加方便页形式的内存映射,相比于传统的Numpy单精度浮点数数组还有一个可哈希的特性。总体来说是一个对于高性能计算十分友好的存储格式,在cudaSPONGE中作为一个分子动力学模拟轨迹输出的格式使用。

本文首发链接为: https://www.cnblogs.com/dechinphy/p/dat.html

作者ID:DechinPhy

更多原著文章: https://www.cnblogs.com/dechinphy/

请博主喝咖啡: https://www.cnblogs.com/dechinphy/gallery/image/379634.html

以上就是电脑114游戏给大家带来的关于Python中Numpy数组的紧凑二进制存储与内存映射读取全部内容,更多攻略请关注电脑114游戏。

电脑114游戏-好玩游戏攻略集合版权声明:以上内容作者已申请原创保护,未经允许不得转载,侵权必究!授权事宜、对本内容有异议或投诉,敬请联系网站管理员,我们将尽快回复您,谢谢合作!

3733游戏盒子最新版 闪耀暖暖9.11日更新内容详解