Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/json/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用Json转储2D Python数组_Python_Json - Fatal编程技术网

使用Json转储2D Python数组

使用Json转储2D Python数组,python,json,Python,Json,我有一个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 = jso

我有一个
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 ...

我只使用过一点numpy,但我认为它以一种特殊的格式在内部保存数据,因此json模块不知道如何处理它是有意义的

将其转换回数组是否有效

json.dumps(numpy.asarray(my_array))

不确定JSON可序列化部分,但可以先将其转换为dict吗?这似乎是一种更自然的JSON输出格式,可以处理数据类型的任何问题


my_dict=dict(zip(my_array[1],my_array[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}'

如果您只是尝试获取数组的漂亮字符串表示形式,而使用字符串数组类型并不能提供所需的表示形式,那么就不能使用消息序列化格式。序列化格式用于保存/传输数据。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)。。。转换为包含数据类型和数组形状的元组:

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和loads命令将是:

strRep = json.dumps(arrayToTuple(arr))
arrayFromTuple(json.loads(strRep))
这也适用于msgpack.dumps和msgpack.loads(更快更紧凑的二进制表示)


可能适用于数组的警告:如果numpy数组是对象数据类型,那么它将不会通过标准方法序列化为完整数组。您必须逐个序列化每个对象,因为它是存储在数组中的对象id,而不是数据。使用dtype作为dtype=“|S”,其中是最大字符串长度,这将使数组可序列化。

对我有效的方法是将较大的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

这会保持我在数组中的顺序吗?(即,行
my\u数组[0,0]:my\u数组[0,1]
应在行
my\u数组[1,0]:my\u数组[1,1]之前打印
等等。但字典保持其键值未排序。当我将其传递给JSON时,如何保证字典中的条目以正确的顺序打印?可能不会,因此可能无法工作。默认情况下,Python dict是无序的。我认为Python 2.7有一个OrderedDict类,但这是否有效取决于您的JSON库将尊重排序。(刚刚注意到您回复了我之前的评论,我已将其删除。在我彻底阅读评论之前,我已经回答了这个问题。这里仍然有点新,抱歉。)您最后的数组索引不正确。对于像这样的2D数组,语法是
array[row][column]
而且,由于您只有两行,第一个索引的最大值应该是
1
。对我来说是可行的,但必须进行解码才能序列化:
返回json.dumps([str(ndarray.dtype),base64.b64encode(ndarray)。解码('utf-8'),ndarray.shape])
然后在反序列化过程中转换为字节数组:
arr=np frombuffer(base64.decodestring(bytearray(loaded[1],'utf-8')),dtype)
也-为了能够base64编码()一个数组,它需要在内存中是连续的,因此如果它不是连续的,则需要转换:
ndarr=np.ascontiguousarray(ndarray,dtype=ndarray.dtype)
asarray()的输出是numpy.ndarray,用于将列表/元组转换为ndarray