Numpy 无法读取包含pickled数据的文件
最近,我在使用Numpy进行数据处理的过程中,遇到了一个问题,即无法读取一个包含pickled数据的文件。在进行调研与实践过程中,我发现了一些有用的知识和技巧,现在将它们整理分享出来,希望对大家有所帮助。
阅读更多:Numpy 教程
什么是pickled数据?
Pickled数据是指经过序列化处理的Python对象(如list、dict等),即将这些对象转化为一些可以方便存储和传输的二进制格式。使用Python的pickle模块,可以非常方便地进行序列化和反序列化操作。
例如,我们可以将一个列表对象pickle化:
import pickle
a_list = [1, 2, 3, 4, 5]
with open('a.pkl', 'wb') as f:
pickle.dump(a_list, f)
.npy文件
.npy文件是Numpy的专用文件格式,用于保存Numpy数组数据。与其他文本格式(如.csv)相比,.npy文件具有更快的读写速度和更小的文件大小,非常适合用于大规模的数据处理和存储。
我们可以在Python中使用Numpy来创建和保存一个数组:
import numpy as np
an_array = np.array([1, 2, 3, 4, 5])
np.save('an_array.npy', an_array)
Numpy无法读取包含pickled数据的文件
当我们尝试读取一个包含pickled数据的文件时,直接使用np.load()方法会出现以下错误信息:
Unable to unserialize the data
这是因为,虽然.npy文件中也是以二进制格式保存数据的,但与pickle化的二进制格式不同。因此,我们需要使用其他方式来读取该文件。
下面,我将介绍两种解决方案。
方案1:使用pickle模块读取文件
由于我们已经知道这个文件中包含了pickle化的对象,因此直接使用pickle模块来读取文件是最简单的方法。
import pickle
with open('a.pkl', 'rb') as f:
data = pickle.load(f)
使用pickle模块的优点是简单直接,并且可以解析包含任何类型Python对象的文件。但是,它不能处理大规模的数值数据,所以对于Numpy数组等数据类型,可能速度会比较慢。此外,读取的数据需要手动转化为Numpy数组格式。
方案2:使用Numpy.lib.format模块读取文件
Numpy.lib.format模块提供了一些可以将pickle化的数据转化为Numpy数组的函数,包括read_array()和read_pickle()方法。
我们可以使用这些函数直接读取包含pickled数据的.npy文件:
import numpy as np
from numpy.lib.format import read_array, read_pickle
with open('an_array.pkl.npy', 'rb') as f:
version = np.lib.format.read_magic(f)
shape, dtype = np.lib.format.read_array_header_1_0(f)
arr = np.lib.format.read_array(f, allow_pickle=True)
使用Numpy.lib.format模块的优点是可以简单地将数据转化为Numpy数组格式,数据类型可以是任意的Numpy数组类型,如int、float、complex、bool和对象数组等。此外,该模块是专门针对Numpy数据设计的,速度较快。
总体来说,如果你要读取包含大规模数值数据的文件,且其中包含的是Numpy数组等数据类型,则建议使用Numpy.lib.format模块来读取文件;如果你要读取的文件中包含了任意类型的Python对象,则直接使用pickle模块更为方便。
总结
在本文中,我们介绍了什么是pickled数据,以及如何使用pickle模块和Numpy.lib.format模块读取包含pickled数据的文件。针对Numpy无法读取该类型文件的问题,我们提供了两种解决方案,并对其优缺点进行了分析和比较。希望这些知识和技巧对于大家在Numpy数据处理和文件读取方面的工作能够有所帮助。
极客笔记