use*_*386 5 python numpy scipy
现在我有一个python程序构建一个相当大的2D numpy数组并使用numpy.savetxt将其保存为制表符分隔的文本文件.numpy数组只包含浮点数.然后,我在一个单独的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
Run Code Online (Sandbox Code Playgroud)
首先,分离出有趣的数字及其指数:
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)
Run Code Online (Sandbox Code Playgroud)
现在您只剩下少量数据元素了。最简单的事情是将它们写入文本文件:
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
Run Code Online (Sandbox Code Playgroud)
这也让您有机会观察数据。在您的 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]))
Run Code Online (Sandbox Code Playgroud)
构造函数的参数Struct
意味着;使用本机日期格式“=”。第一个和第二个数据元素是无符号整数“I”,第三个元素是双精度“d”。
在您的 C++ 程序中,最好将这些数据作为二进制数据读入打包的struct
.
编辑:更新了二维数组的答案。