技术背景

一般情况下我们会选择使用明文形式来存储数据,如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

Python存储与读写二进制文件的更多相关文章

  1. Python之文件读写

    本节内容: I/O操作概述 文件读写实现原理与操作步骤 文件打开模式 Python文件操作步骤示例 Python文件读取相关方法 文件读写与字符编码 一.I/O操作概述 I/O在计算机中是指Input ...

  2. [Matlab+C/C++] 读写二进制文件

    introduction 因为Matlab操作简单.方便,它被应用于很多领域:音频处理,图像处理,数值计算等.尽管MATLAB容易操作,但受限于他的语言解释机制,MATLAB的执行速度通常较低.C/C ...

  3. Python中怎么读写文件

    python中对文件的操作大概分为三步:打开文件.操作文件(读.写.追加写入).关闭文件. 1.无论对文件做哪种操作,操作前首先要保证文件被打开了,即需要一个打开的操作. 例:open(XXX.txt ...

  4. 【转】Python之文件读写

    [转]Python之文件读写 本节内容: I/O操作概述 文件读写实现原理与操作步骤 文件打开模式 Python文件操作步骤示例 Python文件读取相关方法 文件读写与字符编码 一.I/O操作概述 ...

  5. (转)Python之文件读写

    Python之文件读写 原文:https://www.cnblogs.com/huilixieqi/p/6494891.html 本节内容: I/O操作概述 文件读写实现原理与操作步骤 文件打开模式 ...

  6. Python IO编程-读写文件

    1.1给出规格化得地址字符串,这些字符串是经过转义的能直接在代码里使用的字符串 需要导入os模块 import os >>>os.path.join('user','bin','sp ...

  7. python 基础-文件读写'r' 和 'rb'区别

    原文链接: python基础-文件读写'r' 和 'rb'区别 一.Python文件读写的几种模式: r,rb,w,wb 那么在读写文件时,有无b标识的的主要区别在哪里呢? 1.文件使用方式标识 'r ...

  8. 【转】C++读写二进制文件

    原文网址:http://blog.csdn.net/lightlater/article/details/6364931 摘要: 使用C++读写二进制文件,在开发中操作的比较频繁,今天有幸找到一篇文章 ...

  9. Python使用openpyxl读写excel文件

    Python使用openpyxl读写excel文件 这是一个第三方库,可以处理xlsx格式的Excel文件.pip install openpyxl安装.如果使用Aanconda,应该自带了. 读取E ...

  10. Android简易实战教程--第十五话《在外部存储中读写文件》

    第七话里面介绍了在内部存储读写文件 点击打开链接. 这样有一个比较打的问题,假设系统内存不够用,杀本应用无法执行,或者本应用被用户卸载重新安装后.以前保存的用户名和密码都不会得到回显.所以,有必要注意 ...

随机推荐

  1. Mybatis 插入后获取主键

    项目结构 数据表结构 pom.xml <?xml version="1.0" encoding="UTF-8"?> <project xmln ...

  2. 扬州万方:基于申威平台的 Curve 块存储在高性能和超融合场景下的实践

    背景 扬州万方科技股份有限公司主要从事通信.计算机和服务器.智能车辆.基础软件等产品的科研生产,是国家高新技术企业.专精特新小巨人企业.国家火炬计划承担单位. 业务介绍 申威处理器是在国家" ...

  3. [MAUI 项目实战] 笔记App:程序设计

    前言 有人说现在记事类app这么多,市场这么卷,为什么还想做一个笔记类App? 一来,去年小孩刚出生,需要一个可以记录喂奶时间的app,发现市面上没有一款app能够在两步内简单记录一个时间,可能iOS ...

  4. STL 算法 <algorithm>,

    STL 算法部分主要由头文件 <algorithm>,<numeric>,<functional > 组成.要使用 STL 中的算法函数必须包含头文件 < a ...

  5. python与c/java的异

    1.注释 #为单行注释 """ 这里是多行注释 """ ''' 这个也可以是多行注释 ''' 2.赋值 在python中赋值不需要特定变量的 ...

  6. golang 实现的零依赖、高性能、并发 mysqldump 工具。

    mysqldump golang 中实现的零依赖.高性能.并发 mysqldump 工具. 项目地址: https://github.com/dengjiawen8955/mysqldump/blob ...

  7. 【ServerSentEvents】服务端单向消息推送

    依赖库: Springboot 不需要而外支持,WebMVC组件自带的类库 浏览器要检查内核是否支持EventSource库 Springboot搭建SSE服务: 这里封装一个服务Bean, 用于管理 ...

  8. 实现一个终端文本编辑器来学习golang语言

    欢迎!这个系列的博文会带你使用golang语言来编写一个你自己的文本编辑器. 首先想说说写这个系列文章的动机. 其实作为校招生加入某头部互联网大厂一转眼已经快4年了.可以说该大厂算是比较早的用gola ...

  9. 大语言模型可以自动生成sql语句吗?

    大语言模型的能力已经是毋庸置疑的了,随着ChatGPT的霸榜,各种语言模型的应用也多了起来,这时候突然有一个意外,那就是:大语言模型可以自动生成sql语句吗? 之所以有这个疑问,主要是因为sql正好是 ...

  10. 并行化强化学习 —— 初探 —— 并行reinforce算法的尝试 (中篇:强化学习在大规模仿真环境下单步交互并行化设计的可行性)

    本篇博客是前篇博客并行化强化学习 -- 初探 -- 并行reinforce算法的尝试 (上篇:强化学习在多仿真环境下单步交互并行化设计的可行性)的继续,文中代码地址为:https://gitee.co ...