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

2025-03-13 08:52:00
admin
原创
53
摘要:问题描述:我想知道如何numpy.array正确保存和加载数据。目前我正在使用该numpy.savetxt()方法。例如,如果我有一个数组markers,如下所示:我尝试通过使用以下方法来保存它:numpy.savetxt('markers.txt', markers) 在其他脚本中我尝试打开以前保存的文件:...

问题描述:

我想知道如何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:我没有执行其他“后台”操作。只是保存和加载,这就是我得到的。提前谢谢您。


解决方案 1:

我发现最可靠的方法是使用np.savetxtwithnp.loadtxt和 not np.fromfile,它们更适合用 写入的二进制文件tofilenp.fromfilenp.tofile方法写入和读取二进制文件,而np.savetxt写入文本文件。例如:

a = np.array([1, 2, 3, 4])
np.savetxt('test1.txt', a, fmt='%d')
b = np.loadtxt('test1.txt', dtype=int)
a == b
# array([ True,  True,  True,  True], dtype=bool)

或者:

a.tofile('test2.dat')
c = np.fromfile('test2.dat', dtype=int)
c == a
# array([ True,  True,  True,  True], dtype=bool)

我使用前一种方法,即使它速度较慢并且会创建更大的文件(有时):二进制格式可以依赖于平台(例如,文件格式取决于系统的字节顺序)。

NumPy 数组有一种独立于平台的格式,可以使用 和np.save来保存和读取np.load

np.save('test3.npy', a)    # .npy extension is added if not given
d = np.load('test3.npy')
a == d
# array([ True,  True,  True,  True], dtype=bool)

解决方案 2:

np.save('data.npy', num_arr) # save
new_num_arr = np.load('data.npy') # load

解决方案 3:

简短的回答是:您应该使用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]]

扩展答案:

最后,这真的取决于您的需求,因为您还可以将其保存为人类可读的格式(请参阅将 NumPy 数组转储到 csv 文件中),或者如果您的文件非常大,甚至可以使用其他库(请参阅在磁盘上保存 numpy 数组的最佳方法以进行扩展讨论)。

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

举个例子,尝试用 pickle 保存它。我只是为了好玩而尝试了,花了至少 30 分钟才意识到,除非我用 以字节模式打开并读取文件,否则 pickle 不会保存我的东西wb。花了一些时间在 Google 上搜索问题、测试潜在的解决方案、理解错误消息等……这是一个小细节,但事实上它已经要求我打开一个文件,这以意想不到的方式使事情变得复杂。除此之外,它还要求我重新阅读这个(顺便说一句,这有点令人困惑):内置打开函数中的模式 a、a+、w、w+ 和 r+ 之间的区别?。

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

因此请使用 interface/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使用未压缩格式(参见文档)将多个数组以未压缩格式保存到单个文件中.npz。如果您决定使用此功能(您被警告要远离标准解决方案,因此可能会出现错误!)您可能会发现您需要使用参数名称来保存它,除非您想使用默认名称。所以如果第一个已经有效(或任何作品都使用它!),请不要使用它!

  • Pickle 还允许执行任意代码。出于安全原因,有些人可能不想使用此功能。

  • 制作人类可读的文件的成本很高等等。可能不值得。

  • 有种东西叫做hdf5大文件。太酷了!https://stackoverflow.com/a/9619713/1601580


请注意,这不是详尽的答案。但对于其他资源,请查看以下内容:

  • 对于 pickle(猜测最佳答案是不要使用 pickle,而是使用np.save):使用 Pickle 保存 Numpy 数组

  • 对于大文件(很棒的答案!比较存储大小、加载保存等等!):https://stackoverflow.com/a/41425878/1601580

  • 对于 matlab(我们必须承认 matlab 有一些非常棒的图!):“转换” Numpy 数组为 Matlab 以及反之亦然

  • 以人类可读的格式保存:将 NumPy 数组转储到 csv 文件中

解决方案 4:

np.fromfile()有一个sep=关键字参数:

如果文件是文本文件,则项目之间的分隔符。空(“”)分隔符表示文件应被视为二进制文件。分隔符中的空格(“”)匹配零个或多个空格字符。仅由空格组成的分隔符必须匹配至少一个空格。

的默认值sep=""意味着np.fromfile()尝试将其作为二进制文件而不是空格分隔的文本文件读取,因此您会得到无意义的值。如果您使用,np.fromfile('markers.txt', sep=" ")您将获得所需的结果。

然而,正如其他人指出的那样,np.loadtxt()这是将文本文件转换为 numpy 数组的首选方法,除非文件需要人类可读,否则通常最好使用二进制格式(例如np.load()/ np.save())。

相关推荐
  政府信创国产化的10大政策解读一、信创国产化的背景与意义信创国产化,即信息技术应用创新国产化,是当前中国信息技术领域的一个重要发展方向。其核心在于通过自主研发和创新,实现信息技术应用的自主可控,减少对外部技术的依赖,并规避潜在的技术制裁和风险。随着全球信息技术竞争的加剧,以及某些国家对中国在科技领域的打压,信创国产化显...
工程项目管理   2577  
  为什么项目管理通常仍然耗时且低效?您是否还在反复更新电子表格、淹没在便利贴中并参加每周更新会议?这确实是耗费时间和精力。借助软件工具的帮助,您可以一目了然地全面了解您的项目。如今,国内外有足够多优秀的项目管理软件可以帮助您掌控每个项目。什么是项目管理软件?项目管理软件是广泛行业用于项目规划、资源分配和调度的软件。它使项...
项目管理软件   1553  
  IPD(Integrated Product Development)流程作为一种先进的产品开发管理模式,在众多企业中得到了广泛应用。其中,技术评审与决策评审是IPD流程中至关重要的环节,它们既有明显的区别,又存在紧密的协同关系。深入理解这两者的区别与协同,对于企业有效实施IPD流程,提升产品开发效率与质量具有重要意义...
IPD管理流程   26  
  本文介绍了以下10款项目管理软件工具:禅道项目管理软件、ClickUp、Freshdesk、GanttPRO、Planview、Smartsheet、Asana、Nifty、HubPlanner、Teamwork。在当今快速变化的商业环境中,项目管理软件已成为企业提升效率、优化资源分配和确保项目按时交付的关键工具。然而...
项目管理系统   21  
  建设工程项目质量关乎社会公众的生命财产安全,也影响着企业的声誉和可持续发展。高质量的建设工程不仅能为使用者提供舒适、安全的环境,还能提升城市形象,推动经济的健康发展。在实际的项目操作中,诸多因素会对工程质量产生影响,从规划设计到施工建设,再到后期的验收维护,每一个环节都至关重要。因此,探寻并运用有效的方法来提升建设工程...
工程项目管理制度   18  
热门文章
项目管理软件有哪些?
曾咪二维码

扫码咨询,免费领取项目管理大礼包!

云禅道AD
禅道项目管理软件

云端的项目管理软件

尊享禅道项目软件收费版功能

无需维护,随时随地协同办公

内置subversion和git源码管理

每天备份,随时转为私有部署

免费试用