深入探究:Numpy中的npy格式

发布时间:2023-05-23

一、npy格式简介

NumPy是Python中用于科学计算的基础包,提供了数组和矩阵计算的支持,是很多数据处理、机器学习相关库的基础依赖。而npy格式则是NumPy中其自带的数据格式,在存储和加载NumPy数组时使用,具有高效性和通用性。 npy格式本质上是一种二进制文件格式,以.npy作为扩展名,由4部分组成:

1. Magic String: \x93NUMPY\x01\x00
2. Major Version Number: uint8
3. Minor Version Number: uint8
4. Header Length: uint16_bigendian(大端模式)

具体而言,在读取.npy文件时,先读取4字节的魔术字符串,判断其是否为NUMPY,即可确定文件格式是否正确。接下来读取版本号和头部长度,进而可以得到数据的类型、形状等信息。头部长度的值为一个16位大端整数(uint16),后续紧跟着的则是一个UTF-8编码的JSON字符串,即ndarray.dump函数存储时保存的数组属性信息。

二、npy格式的优势

相较于其他常见的数据格式,npy格式具有下列优点:

  1. 快速、高效:npy文件的二进制格式非常紧凑,数据可以直接在内存中复制,即使处理大型数据也能够快速加载。
  2. 通用性:npy格式被NumPy Python库原生支持,可以被几乎所有编程语言使用。
  3. 可压缩性:npy格式可以被压缩为ZIP格式,这大大减少了文件大小,有时甚至可以达到原始文件大小的10%以下。

三、npy格式的使用实例

1. 创建numpy数组

要创建一个numpy数组,我们可以使用numpy的array()函数,并在其中传递要创建的数组。

import numpy as np
a = np.array([1, 2, 3, 4, 5])
np.save('array.npy', a)

这里,我们创建了一个名为“array.npy”的文件,在其中存储了名为“a”的数组。注意,一定要使用“.npy”扩展名,否则会出现文件格式错误。

2. 读取numpy数组

要读取一个以.npy格式存储的numpy数组,我们可以使用numpy的load()函数。以下是读取和打印数组的示例:

import numpy as np
a = np.load('array.npy')
print(a)

当然,我们也可以查看这个数组的大小、形状、元素类型等属性:

print(a.dtype)
print(a.shape)
print(a.size)

3. 压缩和解压缩numpy数组

我们可以将.npy文件压缩为ZIP格式,来减少文件大小,也可以将压缩后的文件解压缩为.npy格式,来读取其中存储的numpy数组数据。 以下是通过Python内置的zipfile库将.npy文件压缩为ZIP文件的示例:

import zipfile
zipobj = zipfile.ZipFile("array.zip", "w")
zipobj.write("array.npy")
zipobj.close()

以下是将ZIP文件解压缩为.npy格式的示例:

zipobj = zipfile.ZipFile("array.zip", "r")
zipobj.extract("array.npy", path="./")
zipobj.close()
arr = np.load("array.npy")
print(arr)

4. 将Python对象保存到numpy数组

我们可以使用numpy的save()函数将Python对象(如列表、字典等)直接存储为.npy格式的文件。 以下是将列表存储为.npy文件的示例:

list_obj = [1, 2, 3, 4, 5]
np.save('list.npy', list_obj)
# 读取
loaded_obj = np.load('list.npy')
print(loaded_obj)

5. 将Python对象保存到numpy数组

我们可以通过定义一个包含每个数据类型的元组列表来创建结构化数组。然后,我们可以使用同样的save()函数将其保存为.npy文件。 以下是创建单个结构化数组并保存为.npy文件的示例:

dt = np.dtype([('name', 'S10'), ('grades', int)])
grades = np.array([('Matt', 90), ('Steve', 85), ('Joy', 87)], dtype=dt)
np.save('grades.npy', grades)
# 读取
data = np.load('grades.npy', allow_pickle=True)
print(data)

6. 多个numpy数组的存储

我们可以使用同样的save()函数一次性存储和读取多个numpy数组。只需将要保存的数组作为参数传递给save()函数即可。 以下是同时保存多个numpy数组的示例:

a = np.array([1, 2, 3, 4])
b = np.array([5, 6, 7, 8])
c = np.array([9, 10, 11, 12])
np.savez('multiple_arrays.npz', a=a, b=b, c=c)
# 读取
data = np.load('multiple_arrays.npz')
print(data['a'])
print(data['b'])
print(data['c'])

总结

.npy文件格式是NumPy库中常用的文件格式之一。通过使用.npy格式,我们可以方便地存储和读取numpy数组,以及其他Python对象。此外,由于.npy格式的高效性和通用性,它也被许多数据处理和机器学习相关库广泛使用。