SimpleJSON и массив NumPy

Каков самый эффективный способ сериализировать массив numpy с помощью simplejson?

41
задан epoch 15 August 2010 в 19:42
поделиться

2 ответа

Я бы использовал simplejson.dumps (somearray.tolist ()) как наиболее удобный подход (если бы я вообще все еще использовал simplejson , что означает, что я застрял на Python 2.5 или более ранней версии; 2.6 и более поздние версии имеют стандартный библиотечный модуль json , который работает точно так же, поэтому, конечно, я бы использовал это, если используемая версия Python поддерживала его ;-).

В поисках большей эффективности вы можете создать подкласс json.JSONEncoder json ; я не знаю, был ли старый simplejson уже предлагал такие возможности настройки), а в методе по умолчанию - особые экземпляры numpy.array , превращая их в список или кортежи «точно вовремя». Я как бы сомневаюсь, что вы получите достаточно от такого подхода с точки зрения производительности, чтобы оправдать усилия.

28
ответ дан 27 November 2019 в 00:08
поделиться

Здесь показано, как преобразовать из одномерного массива NumPy в JSON и обратно в массив:

try:
    import json
except ImportError:
    import simplejson as json
import numpy as np

def arr2json(arr):
    return json.dumps(arr.tolist())
def json2arr(astr,dtype):
    return np.fromiter(json.loads(astr),dtype)

arr=np.arange(10)
astr=arr2json(arr)
print(repr(astr))
# '[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]'
dt=np.int32
arr=json2arr(astr,dt)
print(repr(arr))
# array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])

Основываясь на ответе Тлауша , здесь это способ JSON-кодирования массива NumPy с сохранением формы и dtype любого Массив NumPy - в том числе со сложным dtype.

class NDArrayEncoder(json.JSONEncoder):
    def default(self, obj):
        if isinstance(obj, np.ndarray):
            output = io.BytesIO()
            np.savez_compressed(output, obj=obj)
            return {'b64npz' : base64.b64encode(output.getvalue())}
        return json.JSONEncoder.default(self, obj)


def ndarray_decoder(dct):
    if isinstance(dct, dict) and 'b64npz' in dct:
        output = io.BytesIO(base64.b64decode(dct['b64npz']))
        output.seek(0)
        return np.load(output)['obj']
    return dct

# Make expected non-contiguous structured array:
expected = np.arange(10)[::2]
expected = expected.view('<i4,<f4')

dumped = json.dumps(expected, cls=NDArrayEncoder)
result = json.loads(dumped, object_hook=ndarray_decoder)

assert result.dtype == expected.dtype, "Wrong Type"
assert result.shape == expected.shape, "Wrong Shape"
assert np.array_equal(expected, result), "Wrong Values"
10
ответ дан 27 November 2019 в 00:08
поделиться
Другие вопросы по тегам:

Похожие вопросы: