【Numpy核心编程攻略:Python数据处理、分析详解与科学计算】1.14 文件IO大师:二进制存储的进阶技巧
1.14 文件IO大师:二进制存储的进阶技巧
目录
1.14.1 NPY文件格式结构解析
NumPy
提供了 npy
文件格式来存储数组数据。本节将详细介绍 npy
文件的结构,并通过示例进行展示。
1.14.1.1 NPY文件头结构
npy
文件头包含了一些元数据信息,这些信息用于描述数组的形状、数据类型和字节序等。文件头的结构如下:
- 魔数(Magic Number):前6个字节,表示文件格式版本。
- 版本号(Version):2个字节,表示文件格式的主版本号和次版本号。
- 字节序(Byte Order):1个字节,表示数据的字节序(大端或小端)。
- 字节长度(Byte Length):4个字节,表示文件头的字节长度。
- 描述符(Descriptor):JSON格式的字符串,包含数组的形状、数据类型等信息。
1.14.1.2 NPY文件格式示例
import numpy as np
# 创建一个 3x3 的数组
data = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
# 保存为 npy 文件
np.save('data.npy', data)
# 读取 npy 文件
loaded_data = np.load('data.npy')
print("从 npy 文件读取的数据:\n", loaded_data)
1.14.1.3 NPY文件头结构解析示意图
1.14.2 内存映射文件处理大型数据集
在处理大型数据集时,内存映射文件(Memory-Mapped File)是一个非常有用的工具。本节将详细介绍如何使用 NumPy
的内存映射功能来处理10GB级的数据集。
1.14.2.1 内存映射文件的基本原理
内存映射文件允许你在不将整个文件加载到内存的情况下,访问和修改文件中的数据。这对于处理大型数据集非常有用,因为它可以显著减少内存使用量。
1.14.2.2 使用mmap处理10GB级数据案例
import numpy as np
import os
# 创建一个 10GB 的文件
file_size = 10 * 1024 * 1024 * 1024 # 10GB
with open('large_data.dat', 'wb') as f:
f.write(np.zeros(file_size, dtype=np.uint8))
# 使用内存映射文件
shape = (10000000, 1000)
dtype = np.float32
# 创建内存映射数组
mmap_array = np.memmap('large_data.dat', dtype=dtype, mode='r+', shape=shape)
# 访问和修改数据
mmap_array[0, 0] = 1.0 # 修改第一个元素
print("第一个元素: ", mmap_array[0, 0]) # 访问第一个元素
# 关闭内存映射数组
mmap_array.flush()
del mmap_array
# 删除文件
os.remove('large_data.dat')
1.14.2.3 内存映射文件的性能优势
内存映射文件的主要优势在于它可以按需加载数据,而不是一次性将整个文件加载到内存中。这可以显著减少内存使用量,并提高数据访问的效率。
1.14.3 跨平台字节序问题解决方案
在多平台环境下,字节序问题(endianness)是一个常见的问题。本节将介绍如何在 NumPy
中处理字节序问题,并通过位操作进行演示。
1.14.3.1 字节序的基本概念
- 大端字节序(Big-Endian):最高有效字节(MSB)存储在最低地址。
- 小端字节序(Little-Endian):最低有效字节(LSB)存储在最低地址。
1.14.3.2 字节序转换的位操作演示
import numpy as np
# 创建一个 32 位整数数组
data = np.array([1, 2, 3, 4], dtype=np.uint32)
# 打印原始数据的字节序
print("原始数据的字节序: ", data.dtype.byteorder)
# 转换字节序
data_swapped = data.byteswap().newbyteorder()
print("转换字节序后的数据: ", data_swapped)
# 通过位操作进行字节序转换
def byteswap_uint32(value):
"""
通过位操作转换 32 位整数的字节序
:param value: 需要转换的 32 位整数
:return: 转换字节序后的 32 位整数
"""
return ((value & 0xFF000000) >> 24) | \
((value & 0x00FF0000) >> 8) | \
((value & 0x0000FF00) << 8) | \
((value & 0x000000FF) << 24)
# 测试位操作的字节序转换
original_value = 0x12345678
swapped_value = byteswap_uint32(original_value)
print(f"原始值: 0x{original_value:08X}, 转换后的值: 0x{swapped_value:08X}")
1.14.3.3 字节序转换的位操作示意图
1.14.4 加密存储与数据压缩实战
在实际应用中,数据的安全性和存储效率是非常重要的。本节将介绍如何使用 NumPy
进行二进制文件的加密和压缩存储。
1.14.4.1 二进制文件加密的基本原理
数据加密通常使用对称加密算法,如 AES(Advanced Encryption Standard)。本节将介绍如何使用 PyCrypto
库进行二进制文件的加密。
1.14.4.2 使用zlib实现压缩存储
zlib
是一个常用的压缩库,可以用于压缩 NumPy
数组数据。本节将介绍如何使用 zlib
进行数据压缩和解压。
import numpy as np
import zlib
# 创建一个 1000x1000 的数组
data = np.random.rand(1000, 1000)
# 将数组转换为二进制字符串
data_binary = data.tobytes()
# 进行数据压缩
compressed_data = zlib.compress(data_binary)
print("压缩前的数据大小: ", len(data_binary), "字节")
print("压缩后的数据大小: ", len(compressed_data), "字节")
# 进行数据解压
decompressed_data = zlib.decompress(compressed_data)
decompressed_array = np.frombuffer(decompressed_data, dtype=data.dtype).reshape(data.shape)
print("解压后的数组形状: ", decompressed_array.shape)
# 验证解压后的数据是否与原始数据一致
assert np.array_equal(data, decompressed_array)
1.14.4.3 加密npy文件的完整方案
import numpy as np
import os
from Crypto.Cipher import AES
from Crypto.Util.Padding import pad, unpad
import base64
# 生成密钥
key = os.urandom(32) # 256 位密钥
# 定义加密函数
def encrypt_npy(file_path, key):
"""
加密 npy 文件
:param file_path: npy 文件路径
:param key: 加密密钥
:return: 加密后的文件路径
"""
# 读取 npy 文件数据
data = np.load(file_path)
data_binary = data.tobytes()
# 创建 AES 加密器
cipher = AES.new(key, AES.MODE_CBC)
# 进行数据加密
encrypted_data = cipher.encrypt(pad(data_binary, AES.block_size))
# 保存加密后的数据
encrypted_file_path = file_path + '.enc'
with open(encrypted_file_path, 'wb') as f:
f.write(cipher.iv) # 保存初始化向量
f.write(encrypted_data) # 保存加密后的数据
return encrypted_file_path
# 定义解密函数
def decrypt_npy(file_path, key):
"""
解密 npy 文件
:param file_path: 加密后的 npy 文件路径
:param key: 解密密钥
:return: 解密后的数组
"""
# 读取加密后的文件数据
with open(file_path, 'rb') as f:
iv = f.read(16) # 读取初始化向量
encrypted_data = f.read()
# 创建 AES 解密器
cipher = AES.new(key, AES.MODE_CBC, iv=iv)
# 进行数据解密
decrypted_data = unpad(cipher.decrypt(encrypted_data), AES.block_size)
# 恢复数组
original_shape = np.load(file_path[:-4] + '.npy').shape
original_dtype = np.load(file_path[:-4] + '.npy').dtype
decrypted_array = np.frombuffer(decrypted_data, dtype=original_dtype).reshape(original_shape)
return decrypted_array
# 创建一个 npy 文件
data = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
np.save('data.npy', data)
# 加密 npy 文件
encrypted_file_path = encrypt_npy('data.npy', key)
# 解密 npy 文件
decrypted_data = decrypt_npy(encrypted_file_path, key)
print("解密后的数组:\n", decrypted_data)
# 删除文件
os.remove('data.npy')
os.remove(encrypted_file_path)
1.14.4.4 加密存储的注意事项
- 密钥管理:确保密钥的安全性,避免泄露。
- 性能:加密和解密操作会增加一定的性能开销,需要在安全性和性能之间进行权衡。
- 文件格式:加密后的文件格式需要特别处理,确保在不同平台上的兼容性。
总结
通过本篇文章的详细讲解和示例,我们对 NumPy
中的文件IO操作有了更深入的理解。主要内容包括:
- NPY文件格式结构解析:介绍了
npy
文件头的结构,并通过示例进行了展示。 - 内存映射文件处理大型数据集:详细讲解了内存映射文件的基本原理,并通过一个10GB级数据的案例展示了其应用。
- 跨平台字节序问题解决方案:介绍了字节序的基本概念,并通过位操作进行了字节序转换的演示。
- 加密存储与数据压缩实战:介绍了如何使用
zlib
进行数据压缩,并通过PyCrypto
库实现了npy
文件的加密和解密。
希望这些内容对你有所帮助,如果你有任何问题或建议,欢迎在评论区留言。我们下一篇文章再见!
参考资料
资料名称 | 链接 |
---|---|
NumPy 官方文档 | https://numpy.org/doc/stable/ |
NPY 文件格式 | https://numpy.org/doc/stable/reference/generated/numpy.lib.format.html |
内存映射文件 | https://numpy.org/doc/stable/reference/generated/numpy.memmap.html |
Python 伪代码生成工具 | https://pypi.org/project/pygenstub/ |
字节序转换 | https://docs.scipy.org/doc/numpy-1.13.0/reference/generated/numpy.ndarray.byteswap.html |
位操作示例 | https://www.geeksforgeeks.org/python-bitwise-operators/ |
PyCrypto 官方文档 | https://pycryptodome.readthedocs.io/en/latest/ |
AES 加密算法 | https://en.wikipedia.org/wiki/Advanced_Encryption_Standard |
zlib 压缩库 | https://docs.python.org/3/library/zlib.html |
跨平台字节序问题 | https://www.venusintel.com/73.html |
内存映射文件性能 | https://stackoverflow.com/questions/56569529/what-is-the-difference-between-numpy-memmap-and-numpy-load-with-mmap-mode |
二进制文件处理 | https://realpython.com/python-binary-files/ |
数据压缩 | https://towardsdatascience.com/data-compression-for-machine-learning-f3f9b91ebcf7 |
如果你觉得这篇文章对你有帮助,感谢点赞、收藏和关注!关注我,了解更多 Python 和 NumPy 的实用技巧。
代码学习,前言技术分享,深度分析编程技术,普及科普编程技术,天天都要敲代码
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· 上周热点回顾(2.24-3.2)