gpt4 book ai didi

python - 将 numpy 数组保存到文件中(尽可能小)

转载 作者:太空狗 更新时间:2023-10-30 00:51:05 25 4
gpt4 key购买 nike

现在我有一个 python 程序构建一个相当大的 2D numpy 数组并使用 numpy.savetxt 将其保存为制表符分隔的文本文件。 numpy 数组只包含 float 。然后,我在单独的 C++ 程序中一次读取一行文件。

我想做的是找到一种方法来完成同样的任务,尽可能少地更改我的代码,这样我就可以减小在两个程序之间传递的文件的大小。

我发现我可以使用 numpy.savetxt 来保存到压缩的 .gz 文件而不是文本文件。这将文件大小从 ~2MB 降低到 ~100kB。

有更好的方法吗?也许我可以将二进制的 numpy 数组写入文件以节省空间吗?如果是这样,我该怎么做才能将它读入 C++ 程序?

谢谢你的帮助。我很感激我能得到的任何指导。

编辑:

有很多零(numpy 数组中可能有 70% 的值是 0.0000)我不确定如何利用它并生成一个我的 C++ 程序可以读取的小文件

最佳答案

由于你有很多零,你只能写出(索引,数字)形式的非零元素。

假设您有一个包含少量非零数字的数组:

In [5]: a = np.zeros((10, 10))

In [6]: a
Out[6]:
array([[ 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.],
[ 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.],
[ 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.],
[ 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.],
[ 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.],
[ 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.],
[ 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.],
[ 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.],
[ 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.],
[ 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.]])

In [7]: a[3,1] = 2.0

In [8]: a[7,4] = 17.0

In [9]: a[9,0] = 1.5

首先,分离有趣的数字及其索引:

In [11]: x, y = a.nonzero()

In [12]: zip(x,y)
Out[12]: [(3, 1), (7, 4), (9, 0)]

In [13]: nonzero = zip(x,y)

现在您只剩下少量数据元素了。最简单的方法是将它们写入文本文件:

In [17]: with open('numbers.txt', 'w+') as outf:
....: for r, k in nonzero:
....: outf.write('{:d} {:d} {:g}\n'.format(r, k, a[r,k]))
....:

In [18]: cat numbers.txt
3 1 2
7 4 17
9 0 1.5

这也让您有机会观察数据。在您的 C++ 程序中,您可以使用 fscanf 读取此数据。

但是您可以通过使用 struct 写入二进制数据来进一步减小大小:

In [17]: import struct

In [19]: c = struct.Struct('=IId')

In [20]: with open('numbers.bin', 'w+') as outf:
....: for r, k in nonzero:
....: outf.write(c.pack(r, k, a[r,k]))

Struct 构造函数的参数意味着;使用 native 日期格式“=”。第一个和第二个数据元素是无符号整数“I”,第三个元素是 double “d”。

在您的 C++ 程序中,最好将此数据作为二进制数据读取到打包的 struct 中。

编辑:为二维数组更新了答案。

关于python - 将 numpy 数组保存到文件中(尽可能小),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15369985/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com