python 保存并从字符串检索数值数组

zf9nrax1  于 2023-01-01  发布在  Python
关注(0)|答案(4)|浏览(76)

我想把一个多维Numpy数组转换成一个字符串,然后再把这个字符串转换回一个等价的Numpy数组。
我不想将Numpy数组保存到文件中(例如,通过savetxtloadtxt接口)。
这可能吗?

ncecgwcz

ncecgwcz1#

您可以使用np.tostringnp.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]])

注意tostring返回的字符串并不保存dtype和原始数组的形状,你必须自己重新提供。
另一个选项是使用np.savenp.saveznp.savez_compressed写入io.BytesIO对象(而不是文件):

import numpy as np
import io

x = np.arange(12).reshape(3,4)
output = io.BytesIO()
np.savez(output, x=x)

字符串由下式给出

content = output.getvalue()

给定字符串,可以使用np.load将其加载回数组:

data = np.load(io.BytesIO(content))
x = data['x']

这个方法也存储dtype和shape。
对于大型数组,np.savez_compressed将提供最小的字符串。
类似地,您可以使用np.savetxtnp.loadtxt

import numpy as np
import io

x = np.arange(12).reshape(3,4)
output = io.BytesIO()
np.savetxt(output, x)
content = output.getvalue()
# '0.000000000000000000e+00 1.000000000000000000e+00 2.000000000000000000e+00 3.000000000000000000e+00\n4.000000000000000000e+00 5.000000000000000000e+00 6.000000000000000000e+00 7.000000000000000000e+00\n8.000000000000000000e+00 9.000000000000000000e+00 1.000000000000000000e+01 1.100000000000000000e+01\n'

x = np.loadtxt(io.BytesIO(content))
print(x)

总结:

  • tostring以字符串的形式提供基础数据,没有dtype或shape
  • savetostring类似,不同之处在于它还保存dtype和shape(. npy格式)
  • savez以npz格式保存数组(未压缩)
  • savez_compressed以压缩npz格式保存数组
  • savetxt将数组格式化为可读格式
4xy9mtcn

4xy9mtcn2#

如果你也想保存dtype,你也可以使用python的pickle模块。

import pickle
import numpy as np

a = np.ones(4)
string = pickle.dumps(a)
pickle.loads(string)
rdlzhqv9

rdlzhqv93#

np.tostring和np.fromstring不再起作用。它们使用np.tobyte,但是它将np.array解析为字节而不是字符串。要做到这一点,请使用ast.literal_eval。
如果列表的元素是2D浮点型,那么ast.literal_eval()在检索时不能处理嵌套列表的列表的列表的很多非常复杂的列表。
因此,最好将list的list解析为dict并转储字符串。
当装入一个保存的转储时,ast.literal_eval()以一种更好的方式将dict作为字符串处理。将字符串转换为dict然后将dict转换为列表的列表

k = np.array([[[0.09898942, 0.22804536],[0.06109612, 0.19022354],[0.93369348, 0.53521671],[0.64630094, 0.28553219]],[[0.94503154, 0.82639528],[0.07503319, 0.80149062],[0.1234832 , 0.44657691],[0.7781163 , 0.63538195]]])

d = dict(enumerate(k.flatten(), 1))
d = str(d) ## dump as string  (pickle and other packages parse the dump as bytes)

m = ast.literal_eval(d) ### convert the dict as str to  dict

m = np.fromiter(m.values(), dtype=float) ## convert m to nparray
ui7jx7zq

ui7jx7zq4#

我使用JSON来实现这一点:

1.编码为JSON

第一步是将其编码为JSON:

import json
import numpy as np
np_array = np.array(
      [[[0.2123842 , 0.45560746, 0.23575005, 0.40605248],
        [0.98393952, 0.03679023, 0.6192098 , 0.00547201],
        [0.13259942, 0.69461942, 0.8781533 , 0.83025555]],

       [[0.8398132 , 0.98341709, 0.25296835, 0.84055815],
        [0.27619265, 0.55544911, 0.56615598, 0.058845  ],
        [0.76205113, 0.18001961, 0.68206229, 0.47252472]]])

json_array = json.dumps(np_array.tolist())
print("converted to: " + str(type(json_array)))
print("looks like:")
print(json_array)

结果是:

converted to: <class 'str'>
looks like:
[[[0.2123842, 0.45560746, 0.23575005, 0.40605248], [0.98393952, 0.03679023, 0.6192098, 0.00547201], [0.13259942, 0.69461942, 0.8781533, 0.83025555]], [[0.8398132, 0.98341709, 0.25296835, 0.84055815], [0.27619265, 0.55544911, 0.56615598, 0.058845], [0.76205113, 0.18001961, 0.68206229, 0.47252472]]]

2.解码回Numpy

要将其转换回numpy数组,可以用途:

list_from_json = json.loads(json_array)
np.array(list_from_json)
print("converted to: " + str(type(list_from_json)))
print("converted to: " + str(type(np.array(list_from_json))))
print(np.array(list_from_json))

它给予你:

converted to: <class 'list'>
converted to: <class 'numpy.ndarray'>
[[[0.2123842  0.45560746 0.23575005 0.40605248]
  [0.98393952 0.03679023 0.6192098  0.00547201]
  [0.13259942 0.69461942 0.8781533  0.83025555]]

 [[0.8398132  0.98341709 0.25296835 0.84055815]
  [0.27619265 0.55544911 0.56615598 0.058845  ]
  [0.76205113 0.18001961 0.68206229 0.47252472]]]

我喜欢这种方法,因为字符串很容易读取,尽管在这种情况下不需要将其存储在文件或其他文件中,但使用这种格式也可以做到这一点。

相关问题