我有一个numpy
数组,我想用Json转储。该数组如下所示:
array([['foo', 'bar', 'something', ...
'more'],
['0.4', '0.7', '0.83', ...
'0.3', '0.62', '0.51']]
我希望将其转储到带有Json 的字符串上,如下所示:
foo: 0.4
bar: 0.7
something: 0.51
...
我尝试过:
import jason
my_string = json.dumps(my_array)
但它抱怨:
"not JSON serializable"
有关如何使用Json
将字符串转储到字符串的任何想法更新
请注意,我不在乎订购,应按以下顺序打印行:
array[0,0] : array[0,1]
array[1,0] : array[1,1]
array[2,0] : array[2,1]
# etc ...
答案 0 :(得分:6)
对我有用 - 因为拥有更大的1024x1002 float64数组 - 转换为base64。
def Base64Encode(ndarray):
return json.dumps([str(ndarray.dtype),base64.b64encode(ndarray),ndarray.shape])
def Base64Decode(jsonDump):
loaded = json.loads(jsonDump)
dtype = np.dtype(loaded[0])
arr = np.frombuffer(base64.decodestring(loaded[1]),dtype)
if len(loaded) > 2:
return arr.reshape(loaded[2])
return arr
''' just to compare '''
def SimpleEncode(ndarray):
return json.dumps(ndarray.tolist())
def SimpleDecode(jsonDump):
return np.array(json.loads(jsonDump))
ipython%timeit结果非常清楚地指向base64:
arr = np.random.random_sample((1000, 1000))
print 'Simple Convert'
%timeit SimpleDecode(SimpleEncode(arr))
print 'Base64 Encoding'
%timeit Base64Decode(Base64Encode(arr))
结果:
Simple Convert
1 loops, best of 3: 1.42 s per loop
Base64 Encoding
10 loops, best of 3: 171 ms per loop
答案 1 :(得分:1)
不确定JSON可序列化部分,但您可以先将它转换为dict吗?这似乎是JSON输出的更自然的格式,并且可以处理数据类型的任何问题。
my_dict = dict(zip(my_array[1], my_array[0]))
答案 2 :(得分:0)
我只使用numpy一点,但我认为它在内部以特殊格式保存数据,所以json模块不知道如何处理它是有道理的。
将它转换回数组吗?
json.dumps(numpy.asarray(my_array))
http://docs.scipy.org/doc/numpy/reference/generated/numpy.asarray.html
答案 3 :(得分:0)
如果所有值都是数字,如果其他所有值都失败,您可以随时手动执行:
my_array = [['0.4', '0.7', '0.83', '0.3', '0.62', '0.51'],
['foo', 'bar', 'something', 'more']]
pairs = zip(my_array[1], my_array[0])
json_values = ('"{}": {}'.format(label, value) for label, value in pairs)
my_string = '{' + ', '.join(json_values) + '}'
print my_string # '{"foo": 0.4, "bar": 0.7, "something": 0.83, "more": 0.3}'
答案 4 :(得分:0)
如果您只是尝试获取数组的漂亮字符串表示形式,并且使用字符串数组类型不能为您提供所需的表示形式,则不应使用消息序列化格式。序列化格式用于保存/传输数据。 Json很好,因为它通常也是人类可读的,但这不是目的,并且将它强制为不同的格式会使它不再是json序列化。甚至savetxt和loadtxt numpy选项也不适用于您想要的格式(重复每列的第一行)。如果必须使用以下代码,则可以进行自己的序列化:
def prettySerialize(inArray):
ids = inArray[0]
strRep = ''
for row in inArray[1:]:
for i,item in enumerate(row):
rowStr = id[i] + ':' + item + '\n'
strRep += rowStr
return strRep
这个问题是它会慢得多,并且阵列的表示要大得多(一遍又一遍地重复“id”行)。我强烈建议使用纯json(或msgpack)解决方案,除非你专门为人类阅读格式化...
这是我用于使用msgpack进行序列化的解决方案(也适用于json)...转换为包含dtype和数组形状的元组:
def arrayToTuple(arr):
if arr is None:
return None
return (arr.dtype.str, arr.shape, arr.tostring())
def arrayFromTuple(tupl):
if tupl is None:
return None
typeStr, shape, dataStr = tupl
resultArray = numpy.fromstring(dataStr, dtype=typeStr).reshape(shape)
return resultArray
所以dumps和load命令是:
strRep = json.dumps(arrayToTuple(arr))
arrayFromTuple(json.loads(strRep))
这也适用于msgpack.dumps和msgpack.loads(更快速更紧凑的二进制表示)。
可能适用于您的数组的警告:如果您的numpy数组是对象dtype,那么它将不会通过标准方法作为完整数组进行序列化。您必须单独序列化每个对象,因为它是存储在数组中的对象id,而不是数据。使用dtype作为dtype ='| S',其中最大字符串长度将使数组可序列化。