Каков самый эффективный способ сериализировать массив numpy с помощью simplejson?
Я бы использовал simplejson.dumps (somearray.tolist ())
как наиболее удобный подход (если бы я вообще все еще использовал simplejson
, что означает, что я застрял на Python 2.5 или более ранней версии; 2.6 и более поздние версии имеют стандартный библиотечный модуль json
, который работает точно так же, поэтому, конечно, я бы использовал это, если используемая версия Python поддерживала его ;-).
В поисках большей эффективности вы можете создать подкласс json.JSONEncoder (в json
; я не знаю, был ли старый simplejson
уже предлагал такие возможности настройки), а в методе по умолчанию
- особые экземпляры numpy.array
, превращая их в список или кортежи «точно вовремя». Я как бы сомневаюсь, что вы получите достаточно от такого подхода с точки зрения производительности, чтобы оправдать усилия.
Здесь показано, как преобразовать из одномерного массива 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"