我想知道如何正确保存和加载numpy.array
数据。目前我正在使用numpy.savetxt()
方法。例如,如果我有一个数组markers
,如下所示:
我尝试使用以下方法保存它:
numpy.savetxt('markers.txt', markers)
在其他脚本中,我尝试打开以前保存的文件:
markers = np.fromfile("markers.txt")
这就是我得到的......
保存的数据首先如下所示:
0.000000000000000000e+00
0.000000000000000000e+00
0.000000000000000000e+00
0.000000000000000000e+00
0.000000000000000000e+00
0.000000000000000000e+00
0.000000000000000000e+00
0.000000000000000000e+00
0.000000000000000000e+00
0.000000000000000000e+00
但是当我通过使用相同的方法保存刚加载的数据时,即。 numpy.savetxt()
它看起来像这样:
1.398043286095131769e-76
1.398043286095288860e-76
1.396426376485745879e-76
1.398043286055061908e-76
1.398043286095288860e-76
1.182950697433698368e-76
1.398043275797188953e-76
1.398043286095288860e-76
1.210894289234927752e-99
1.398040649781712473e-76
我做错了什么? PS我没有其他“后台”操作。只需保存和加载,这就是我得到的。提前谢谢。
答案 0 :(得分:90)
我发现执行此操作的最可靠方法是将np.savetxt
与np.loadtxt
一起使用,而不是np.fromfile
,这更适合使用tofile
编写的二进制文件。 np.fromfile
和np.tofile
方法写入和读取二进制文件,而np.savetxt
写入文本文件。
所以,例如:
In [1]: a = np.array([1, 2, 3, 4])
In [2]: np.savetxt('test1.txt', a, fmt='%d')
In [3]: b = np.loadtxt('test1.txt', dtype=int)
In [4]: a == b
Out[4]: array([ True, True, True, True], dtype=bool)
或者:
In [5]: a.tofile('test2.dat')
In [6]: c = np.fromfile('test2.dat', dtype=int)
In [7]: c == a
Out[7]: array([ True, True, True, True], dtype=bool)
我使用前一种方法,即使它较慢并创建更大的文件(有时):二进制格式可能与平台有关(例如,文件格式取决于系统的字节顺序)。
NumPy阵列有一个平台独立的格式,可以使用np.save
和np.load
保存和阅读:
In [8]: np.save('test3.npy', a) # .npy extension is added if not given
In [9]: d = np.load('test3.npy')
In [10]: a == d
Out[10]: array([ True, True, True, True], dtype=bool)
答案 1 :(得分:5)
np.save('data.npy', num_arr) # save
new_num_arr = np.load('data.npy') # load
答案 2 :(得分:3)
np.fromfile()
有一个sep=
关键字参数:
如果文件是文本文件,则在项目之间分隔。空(“”)分隔符表示该文件应被视为二进制文件。分隔符中的空格(“”)匹配零个或多个空白字符。仅由空格组成的分隔符必须至少匹配一个空格。
默认值sep=""
表示np.fromfile()
尝试将其读取为二进制文件而不是空格分隔的文本文件,因此您将获得无意义的值。如果您使用np.fromfile('markers.txt', sep=" ")
,您将获得所需的结果。
然而,正如其他人所指出的,np.loadtxt()
是将文本文件转换为numpy数组的首选方法,除非文件需要人类可读,否则通常最好使用二进制格式(例如{ {1}} / np.load()
)。
答案 3 :(得分:1)
要简短回答,请使用np.save
和np.load
。这些方法的优点是它们是由numpy库的开发人员制作的,并且已经可以使用(而且可能已经很好地进行了优化),例如。
import numpy as np
from pathlib import Path
path = Path('~/data/tmp/').expanduser()
path.mkdir(parents=True, exist_ok=True)
lb,ub = -1,1
num_samples = 5
x = np.random.uniform(low=lb,high=ub,size=(1,num_samples))
y = x**2 + x + 2
np.save(path/'x', x)
np.save(path/'y', y)
x_loaded = np.load(path/'x.npy')
y_load = np.load(path/'y.npy')
print(x is x_loaded) # False
print(x == x_loaded) # [[ True True True True True]]
扩展答案:
最后,这实际上取决于您的需求,因为您还可以将其保存为人类可读的格式(请参阅此Dump a NumPy array into a csv file),或者如果文件非常大(另请参见此best way to preserve numpy arrays on disk也可以保存为其他库)展开讨论)。
但是,(由于您在问题中使用“适当”一词,因此进行了扩展)我仍然认为开箱即用(和大多数代码!)使用numpy函数最有可能满足大多数用户需求。最重要的原因是它已经可以工作。出于其他原因尝试使用其他东西可能会使您出乎意料的长兔子洞,以弄清为什么它不起作用并迫使它起作用。
例如,尝试用泡菜保存它。我试着只是为了好玩,花了至少30分钟的时间才意识到,除非我用wb
以字节模式打开并读取文件,否则泡菜不会保存我的东西。花时间去Google,试一试,理解错误消息等。。。小细节,但事实是它已经需要我打开文件,这以意想不到的方式使事情变得复杂。要补充一点,它要求我重新阅读({btw有点令人困惑)Difference between modes a, a+, w, w+, and r+ in built-in open function?。
因此,如果有一个满足您需要的界面,除非有充分的理由(非常)(例如,与matlab兼容,或者出于某种原因您确实想读取文件并进行打印),否则请使用它python确实不能满足您的需求,这可能是有问题的)。此外,最有可能的情况是,如果您需要对其进行优化,则可以在以后找到答案(而不是花很多时间调试诸如打开简单的numpy文件之类的无用的东西)。
因此,请使用界面/ numpy提供。它可能并不完美,这很可能很好,尤其是对于已经存在numpy的库而言。
我已经花了很多时间用numpy来保存和加载数据,所以请乐在其中,希望对您有所帮助!
import numpy as np
import pickle
from pathlib import Path
path = Path('~/data/tmp/').expanduser()
path.mkdir(parents=True, exist_ok=True)
lb,ub = -1,1
num_samples = 5
x = np.random.uniform(low=lb,high=ub,size=(1,num_samples))
y = x**2 + x + 2
# using save (to npy), savez (to npz)
np.save(path/'x', x)
np.save(path/'y', y)
np.savez(path/'db', x=x, y=y)
with open(path/'db.pkl', 'wb') as db_file:
pickle.dump(obj={'x':x, 'y':y}, file=db_file)
## using loading npy, npz files
x_loaded = np.load(path/'x.npy')
y_load = np.load(path/'y.npy')
db = np.load(path/'db.npz')
with open(path/'db.pkl', 'rb') as db_file:
db_pkl = pickle.load(db_file)
print(x is x_loaded)
print(x == x_loaded)
print(x == db['x'])
print(x == db_pkl['x'])
print('done')
对我学到的一些评论:
np.save
如预期的那样,已经对其进行了很好的压缩(请参见https://stackoverflow.com/a/55750128/1601580),开箱即用,无需打开任何文件。清洁。简单。高效的。使用它。np.savez
使用未压缩格式(请参见docs)Save several arrays into a single file in uncompressed
。npz format.
如果您决定使用此格式(警告您不要使用标准解决方案,所以可能会发现错误!),您可能会发现需要使用参数名称来保存它,除非您要使用默认名称。因此,如果第一个已经使用(或任何作品都使用它!),请不要使用它。hdf5
的东西。凉! https://stackoverflow.com/a/9619713/1601580 请注意,这不是详尽的答案。但对于其他资源,请检查以下内容:
np.save
使用泡菜):Save Numpy Array using Pickle