8

在我的程序中,我正在使用各种不同大小的 numpy 数组。我需要将它们存储到 XML 文件中以备后用。我没有将它们写入二进制文件,因此我将所有数据放在一个位置(XML 文件),而不是分散在 200 个文件中。

所以我尝试使用 numpy 的 array_str() 方法将数组转换为字符串。生成的 XML 如下所示:

-<Test date="2013-07-10-17:19">
    <Neurons>5</Neurons>
    <Errors>[7.7642140551985428e-06, 7.7639131137987232e-06]</Errors>
    <Iterations>5000</Iterations>
    <Weights1>[[ 0.99845902 -0.70780512 0.26981375 -0.6077122 0.09639695] [ 0.61856711 -0.74684913 0.20099992 0.99725171 -0.41826754] [ 0.79964397 0.56620812 -0.64055346 -0.50572793 -0.50100635]]</Weights1>
    <Weights2>[[-0.1851452 -0.22036027] [ 0.19293429 -0.1374252 ] [-0.27638478 -0.38660974] [ 0.30441414 -0.01531598] [-0.02478953 0.01823584]]</Weights2>
</Test>

权重是我要存储的值。现在的问题是 numpy 的 fromstring() 方法显然无法重新加载这些......我得到“ValueError:字符串大小必须是元素大小的倍数”

我用“np.array_str(w1)”编写它们并尝试用“np.fromstring(w_str1)”读取它们。显然,即使它有效,结果也只是一个一维数组,所以我必须手动恢复形状。呃,这已经很痛苦了,因为我也必须以某种方式存储它。

正确执行此操作的最佳方法是什么?最好也可以保存我的数组的形状和数据类型,而无需对每一件小事进行手动内务处理。

4

4 回答 4

16

Numpy 提供了一种将许多数组存储在压缩文件中的简单方法:

a = np.arange(10)
b = np.arange(10)
np.savez_compressed('file.npz', a=a, b=b)

您甚至可以在保存时更改数组名称,例如np.savez_compressed('file.npz', newa=a, newb=b)

要读取保存的文件,请使用np.load(),它会返回一个NpzFile像字典一样工作的实例:

loaded = np.load('file.npz')

加载数组:

a_loaded = loaded['a']
b_loaded = loaded['b']

或者:

from operator import itemgetter
g = itemgetter( 'a', 'b' )
a_loaded, b_loaded = g(np.load('file.npz'))
于 2013-07-10T15:47:24.483 回答
3

不幸的是,没有简单的方法可以将当前输出读回 numpy。输出在您的 xml 文件上看起来不太好,但您可以创建数组的可读版本,如下所示:

>>> import cStringIO
>>> a = np.array([[ 0.99845902, -0.70780512, 0.26981375, -0.6077122, 0.09639695], [ 0.61856711, -0.74684913, 0.20099992, 0.99725171, -0.41826754], [ 0.79964397, 0.56620812, -0.64055346, -0.50572793, -0.50100635]])
>>> out_f = cStringIO.StringIO()
>>> np.savetxt(out_f, a, delimiter=',')
>>> out_f.getvalue()
'9.984590199999999749e-01,-7.078051199999999543e-01,2.698137500000000188e-01,-6.077122000000000357e-01,9.639694999999999514e-02\n6.185671099999999756e-01,-7.468491299999999722e-01,2.009999199999999986e-01,9.972517100000000134e-01,-4.182675399999999932e-01\n7.996439699999999817e-01,5.662081199999999814e-01,-6.405534600000000189e-01,-5.057279300000000477e-01,-5.010063500000000447e-01\n'

并将其加载回:

>>> in_f = cStringIO.StringIO(out_f.getvalue())
>>> np.loadtxt(in_f, delimiter=',')
array([[ 0.99845902, -0.70780512,  0.26981375, -0.6077122 ,  0.09639695],
       [ 0.61856711, -0.74684913,  0.20099992,  0.99725171, -0.41826754],
       [ 0.79964397,  0.56620812, -0.64055346, -0.50572793, -0.50100635]])
于 2013-07-10T16:02:22.417 回答
1

如果您真的想保留您拥有的初始 XML 格式,我的建议是使用模块在和json之间进行转换。ndarraystring

检查以下内容:

import json, numpy

w1 = numpy.array([[ 0.99845902, -0.70780512, 0.26981375, -0.6077122, 0.09639695],
                  [ 0.61856711, -0.74684913, 0.20099992, 0.99725171, -0.41826754],
                  [ 0.79964397, 0.56620812, -0.64055346, -0.50572793, -0.50100635]])

print w1
print

#####

w1string = json.dumps(w1.tolist())

## NOW YOU COULD PASS "w1string" TO/FROM XML

#####


print w1string
print

w1back = numpy.array(json.loads(w1string))

print w1back
print
于 2013-10-10T16:58:13.820 回答
0

您可以使用numpy.ndarray.tostring()将数组转换为字符串(实际上是字节数组)。 Numpy.ndarray.tostring()

然后这可以稍后用于使用numpy.fromstring()读回数组。

In [138]: x = np.arange(12).reshape(3,4)

In [139]: x.tostring()
Out[139]: '\x00\x00\x00\x00\x01\x00\x00\x00\x02\x00\x00\x00\x03\x00\x00\x00\x04\x00\x00\x00\x05\x00\x00\x00\x06\x00\x00\x00\x07\x00\x00\x00\x08\x00\x00\x00\t\x00\x00\x00\n\x00\x00\x00\x0b\x00\x00\x00'

In [140]: np.fromstring(x.tostring(), dtype=x.dtype).reshape(x.shape)
Out[140]: 
array([[ 0,  1,  2,  3],
       [ 4,  5,  6,  7],
       [ 8,  9, 10, 11]])
于 2015-06-01T12:25:54.647 回答