Json编码器和解码器用于复杂的numpy数组

9 浏览
0 Comments

Json编码器和解码器用于复杂的numpy数组

我正在尝试将一个复杂的numpy数组进行JSON编码,我找到了astropy中的一个实用程序(http://astropy.readthedocs.org/en/latest/_modules/astropy/utils/misc.html#JsonCustomEncoder)用于此目的:

import numpy as np
class JsonCustomEncoder(json.JSONEncoder):
    """ <为了简洁起见进行了裁剪> """
    def default(self, obj):
        if isinstance(obj, (np.ndarray, np.number)):
            return obj.tolist()
        elif isinstance(obj, (complex, np.complex)):
            return [obj.real, obj.imag]
        elif isinstance(obj, set):
            return list(obj)
        elif isinstance(obj, bytes):  # pragma: py3
            return obj.decode()
        return json.JSONEncoder.default(self, obj)

这对于复杂的numpy数组效果很好:

test = {'some_key':np.array([1+1j,2+5j, 3-4j])}

导出的结果如下:

encoded = json.dumps(test, cls=JsonCustomEncoder)
print encoded
>>> {"some key": [[1.0, 1.0], [2.0, 5.0], [3.0, -4.0]]}

问题是,我不知道如何自动将其读回一个复杂的数组。例如:

json.loads(encoded)
>>> {"some_key": [[1.0, 1.0], [2.0, 5.0], [3.0, -4.0]]}

你们能帮我找到一种方法来覆盖loads/解码,以便它能够推断出这必须是一个复杂的数组吗?即,它不应该是一个两个元素项的列表,而是应该将其重新放入一个复杂的数组中。JsonCustomDecoder没有可以覆盖的default()方法,而且编码的文档对我来说术语太多。

0
0 Comments

问题的出现原因是在编码和解码复杂的NumPy数组时,只有当数据是C_CONTIGUOUS(按C顺序存储)时,才能正常工作。如果对数据进行了转置,那么数据就不再是C_CONTIGUOUS。解决方法是在传递对象到b64encode之前使用'np.ascontiguousarray()'函数,将对象转换为C_CONTIGUOUS的形式。

具体来说,原来的代码中使用了base64.b64encode(obj.data),需要修改为base64.b64encode(np.ascontiguousarray(obj).data)

这样做的原因是,np.ascontiguousarray()函数只会在数据不是C_CONTIGUOUS时才执行操作,因此对于已经是C_CONTIGUOUS的数据没有额外的性能损耗。感谢原作者提供了这个解决方法,否则我真的对此一无所知。

还有一种解决方法是使用base64.b64encode(obj.copy(order='C')),这种方法也可以解决问题。

总之,在编码和解码复杂的NumPy数组时,需要注意数据的存储方式是否为C_CONTIGUOUS,如果不是,则需要使用np.ascontiguousarray()函数进行转换,以确保正确的编码和解码。

0
0 Comments

在这篇文章中,作者分享了一个解决复杂numpy数组的编码和解码问题的解决方案。问题的出现是因为在嵌套字典中存在多层次的数组,而json库在默认情况下无法正确处理这种情况。为了解决这个问题,作者使用了hpaulj在Stack Overflow上的答案,并对其进行了修改。

解决方案的核心是自定义了一个NumpyEncoder类,继承自json.JSONEncoder。在该类中,作者重写了default方法,当遇到numpy数组时,将其转换为一个包含dtype、shape和经过base64编码的数据的字典。

另外,作者还定义了一个名为json_numpy_obj_hook的函数,用于解码之前编码的numpy数组。该函数检查字典是否包含特定的键值对,如果存在,则将base64解码后的数据重新转换为numpy数组,并恢复其原始的shape和dtype。

作者还重载了json库的一些方法,如dumps、loads、dump和load,以便在使用json编码和解码时默认使用上述的编码器和解码器。

最后,作者在代码的末尾提供了一个示例,展示了如何使用这个解决方案。在示例中,作者创建了一个复杂的numpy数组,并将其嵌套到多层次的字典中。然后,通过将该字典转换为json字符串,再通过解码器将其恢复回原始数据。最后,作者打印出了原始数据、嵌套字典和解码后的数据,以验证解决方案的有效性。

总之,这个解决方案提供了一个可以编码和解码复杂numpy数组的方法,使得在使用json进行数据传输和存储时更加方便和灵活。

0
0 Comments

在这段内容中,提到了一个关于在复杂的numpy数组中进行JSON编码和解码的问题。问题的出现是因为对于复杂数组的编码将其呈现为一个列表的列表。然后解码器需要将其转换回具有适当dtype的数组。解决方法之一是使用字典添加一个或多个键来标记该变量为复杂的nparray。另一种解决方法是使用编码时的字典键来标记数组的dtype和形状。这样的解码方法可以处理更一般的数组,包括具有复杂dtype的数组。

另一种解决方案是使用一个自定义的解码函数(object_hook函数),该函数将接受一个字典并返回一个数组(如果可能的话)。这个自定义解码函数可以将每个JSON数组转换成一个np.array,并将具有两列的数组转换成一个一维复数数组。

为了处理更一般的列表和其他数组维度,可以改进自定义解码函数。这个改进的解码函数可以处理嵌套的字典,其中数组在不同的层级中被嵌藏。为了更好地处理这个问题,编码时需要明确标识应该转换回数组和复杂数组的对象。

总之,通过使用自定义的解码函数和对编码时的字典进行修改,可以解决对复杂numpy数组进行JSON编码和解码的问题。这种方法可以处理各种形状和dtype的数组,并可以处理嵌套的字典结构。

0