SimpleJSON与NumPy数组

43 投票
9 回答
39526 浏览
提问于 2025-04-16 02:49

用simplejson把numpy数组转成字符串的最有效方法是什么?

9 个回答

17

我找到了一段代码,可以把一维的numpy数组放进字典里,然后转成json格式。我试过了,效果很好。

class NumpyAwareJSONEncoder(json.JSONEncoder):
    def default(self, obj):
        if isinstance(obj, numpy.ndarray) and obj.ndim == 1:
            return obj.tolist()
        return json.JSONEncoder.default(self, obj)

我的字典叫做'results'。下面是我怎么把它写入文件"data.json"的:

j=json.dumps(results,cls=NumpyAwareJSONEncoder)
f=open("data.json","w")
f.write(j)
f.close()
80

为了保持数据类型和维度,可以试试这个:

import base64
import json
import numpy as np

class NumpyEncoder(json.JSONEncoder):

    def default(self, obj):
        """If input object is an ndarray it will be converted into a dict 
        holding dtype, shape and the data, base64 encoded.
        """
        if isinstance(obj, np.ndarray):
            if obj.flags['C_CONTIGUOUS']:
                obj_data = obj.data
            else:
                cont_obj = np.ascontiguousarray(obj)
                assert(cont_obj.flags['C_CONTIGUOUS'])
                obj_data = cont_obj.data
            data_b64 = base64.b64encode(obj_data)
            return dict(__ndarray__=data_b64,
                        dtype=str(obj.dtype),
                        shape=obj.shape)
        # Let the base class default method raise the TypeError
        super(NumpyEncoder, self).default(obj)


def json_numpy_obj_hook(dct):
    """Decodes a previously encoded numpy ndarray with proper shape and dtype.

    :param dct: (dict) json encoded ndarray
    :return: (ndarray) if input was an encoded ndarray
    """
    if isinstance(dct, dict) and '__ndarray__' in dct:
        data = base64.b64decode(dct['__ndarray__'])
        return np.frombuffer(data, dct['dtype']).reshape(dct['shape'])
    return dct

expected = np.arange(100, dtype=np.float)
dumped = json.dumps(expected, cls=NumpyEncoder)
result = json.loads(dumped, object_hook=json_numpy_obj_hook)


# None of the following assertions will be broken.
assert result.dtype == expected.dtype, "Wrong Type"
assert result.shape == expected.shape, "Wrong Shape"
assert np.allclose(expected, result), "Wrong Values"
28

我会使用 simplejson.dumps(somearray.tolist()) 作为最 方便 的方法(如果我还在用 simplejson 的话,这意味着我在用 Python 2.5 或更早的版本;因为从 2.6 版本开始,Python 自带的库里有一个 json 模块,功能和这个一样,所以如果我用的 Python 版本支持的话,我当然会用这个;-)。

如果想要更高效一点,你 可以 通过继承 json.JSONEncoder (在 json 里;我不确定旧版的 simplejson 是否已经提供了这样的自定义功能),在 default 方法里,专门处理 numpy.array 的实例,把它们“及时”转换成列表或元组。不过,我有点怀疑通过这种方法能在性能上获得足够的提升,来值得你付出这样的努力。

撰写回答