如何正确保存和加载numpy.array()数据?

blu*_*xel 75 python arrays numpy

我想知道,如何numpy.array正确保存和加载数据.目前我正在使用该numpy.savetxt()方法.例如,如果我有一个数组markers,看起来像这样:

在此输入图像描述

我尝试通过以下方式保存它:

numpy.savetxt('markers.txt', markers)
Run Code Online (Sandbox Code Playgroud)

在其他脚本中,我尝试打开以前保存的文件:

markers = np.fromfile("markers.txt")
Run Code Online (Sandbox Code Playgroud)

这就是我得到的......

在此输入图像描述

保存的数据首先如下所示:

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
Run Code Online (Sandbox Code Playgroud)

但是当我通过使用相同的方法保存刚加载的数据时,即.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
Run Code Online (Sandbox Code Playgroud)

我究竟做错了什么?PS我没有其他"后台"操作.只需保存和加载,这就是我得到的.先感谢您.

xnx*_*xnx 112

我发现这样做的最可靠的方法是使用np.savetxtwith np.loadtxt而不是np.fromfile哪个更适合用它编写的二进制文件tofile.该np.fromfilenp.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)
Run Code Online (Sandbox Code Playgroud)

要么:

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)
Run Code Online (Sandbox Code Playgroud)

我使用前一种方法,即使它较慢并创建更大的文件(有时):二进制格式可能与平台有关(例如,文件格式取决于系统的字节顺序).

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)
Run Code Online (Sandbox Code Playgroud)

  • `.npy`文件(例如由`np.save()`生成)*与*平台无关,并且比文本文件更紧凑,创建更快. (33认同)
  • @tegan `np.savez` 保存了几个未压缩的数组 - `np.savez_compressed` 将压缩它们 - 还没有 `np.save_compressed`。见 https://docs.scipy.org/doc/numpy-1.15.1/reference/routines.io.html (3认同)
  • 如果要压缩输出,也可以使用np.savez。 (2认同)

She*_*zod 19

np.save('data.npy', num_arr) # save
new_num_arr = np.load('data.npy') # load
Run Code Online (Sandbox Code Playgroud)

  • @Scott 由于这个解决方案已经包含在 4 年前接受的答案中(在最底部),因此确实有一个论点支持将其保留为社区 Wiki。**我个人发现这个答案是迄今为止最有用的**。 (3认同)

Cha*_*ker 7

对于简短的回答,您应该使用np.savenp.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]]
Run Code Online (Sandbox Code Playgroud)

扩展答案:

最后,它真的取决于您的需要,因为您还可以将其保存为人类可读的格式(请参阅此Dump a NumPy array into a csv file),或者如果您的文件非常大,甚至可以使用其他库(请参阅此最佳方法来保留 numpy 数组在磁盘上进行扩展讨论)。

但是,(由于您在问题中使用了“正确”一词,因此进行了扩展)我仍然认为使用开箱即用的 numpy 函数(和大多数代码!)最有可能满足大多数用户的需求。最重要的原因是它已经起作用了。出于任何其他原因尝试使用其他东西可能会让你陷入一个意想不到的长兔子洞,以找出它为什么不起作用并强制它起作用。

以尝试用泡菜保存它为例。我只是为了好玩而尝试这样做,我花了至少 30 分钟才意识到泡菜不会保存我的东西,除非我用wb. 花时间去谷歌,尝试一下,了解错误信息等......细节很小,但事实是它已经要求我以意想不到的方式打开一个复杂的东西。补充一点,它需要我重新阅读这个(顺便说一句,这有点令人困惑)内置 open 函数中模式 a、a+、w、w+ 和 r+ 之间的区别?.

因此,如果有满足您需求的接口,请使用它,除非您有(非常)充分的理由(例如与 matlab 兼容或出于某种原因您真的想读取文件并在 python 中打印确实不能满足您的需要,这可能有问题)。此外,很可能如果您需要优化它,您稍后会发现(而不是花费很长时间调试无用的东西,例如打开一个简单的 numpy 文件)。

所以使用 interface/numpy provide。它可能并不完美,但很可能没问题,尤其是对于像 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')
Run Code Online (Sandbox Code Playgroud)

关于我学到的一些评论:

  • np.save正如预期的那样,这已经很好地压缩了它(参见/sf/answers/3902508991/),开箱即用,无需打开任何文件。干净的。简单。高效的。用它。
  • np.savez使用未压缩的格式(参见文档Save several arrays into a single file in uncompressed .npz format.如果您决定使用它(您被警告远离标准解决方案,因此期待错误!)您可能会发现您需要使用参数名称来保存它,除非您想使用默认名称。因此,如果第一个已经有效(或任何作品使用它!),请不要使用它
  • Pickle 还允许任意代码执行。出于安全原因,有些人可能不想使用它。
  • 人类可读的文件制作成本很高,等等。可能不值得。
  • 有一些hdf5需要大文件的东西。凉爽的!/sf/answers/673379941/

请注意,这不是详尽的答案。但是对于其他资源,请检查: