매트릭스 치수를 유지하면서 numpy 어레이를 시리얼화하려면 어떻게 해야 합니까?
numpy.array.tostring
매트릭스 치수에 관한 정보가 보존되어 있지 않은 것 같습니다(이 질문 참조).사용자는 다음 주소로 콜을 발행해야 합니다.numpy.array.reshape
이 정보를 유지하면서 numpy 어레이를 JSON 형식으로 시리얼화하는 방법이 있습니까?
메모: 어레이에는 int, float 또는 bool이 포함될 수 있습니다.전치된 어레이를 기대하는 것이 타당합니다.
주 2: 이것은 streamparse를 사용하여 numpy 어레이를 Storm topology에 전달하기 위한 목적으로 행해지고 있습니다.
pickle.dumps
또는 엔디안니스 문제, 연속되지 않은 배열 또는 이상한 구조화된 dtype이 존재하는 경우에도 임의의 NumPy 배열을 재구성하는 데 필요한 모든 정보를 인코딩합니다.엔디안니스 문제가 가장 중요할 것입니다.원하는 것은 아닙니다.array([1])
되다array([16777216])
어레이를 빅 엔디언 머신에 로드했기 때문입니다. pickle
더 선택일 만,save
에는 포맷의 근거에 따라 독자적인 이점이 있습니다.
JSON으로의 시리얼화 또는 바이테스트링의 옵션을 제공하고 있습니다.원래의 질문자는 JSON 시리얼화 가능한 출력이 필요했지만, 여기 오는 대부분의 사람은 그렇지 않을 것입니다.
pickle
삭제:
import pickle
a = # some NumPy array
# Bytestring option
serialized = pickle.dumps(a)
deserialized_a = pickle.loads(serialized)
# JSON option
# latin-1 maps byte n to unicode code point n
serialized_as_json = json.dumps(pickle.dumps(a).decode('latin-1'))
deserialized_from_json = pickle.loads(json.loads(serialized_as_json).encode('latin-1'))
numpy.save
형식을 사용하고 에 파일에 쓸 만, 이 할 때는 쓸 수 .io.BytesIO
:
a = # any NumPy array
memfile = io.BytesIO()
numpy.save(memfile, a)
serialized = memfile.getvalue()
serialized_as_json = json.dumps(serialized.decode('latin-1'))
# latin-1 maps byte n to unicode code point n
또한 역직렬화 방법:
memfile = io.BytesIO()
# If you're deserializing from a bytestring:
memfile.write(serialized)
# Or if you're deserializing from JSON:
# memfile.write(json.loads(serialized_as_json).encode('latin-1'))
memfile.seek(0)
a = numpy.load(memfile)
편집: 질문의 코멘트에서 알 수 있듯이, 이 솔루션은 멀티 타입의 구조화 어레이가 아닌, 「일반」의 숫자 어레이(플로트, int, 부울 등)에 대응하고 있습니다.
모든 차원 및 데이터 유형의 Numpy 어레이를 시리얼화하는 솔루션
데이터 타입이나 차원에 관계없이 단순히 numpy 어레이를 시리얼화할 수 없는 것으로 알고 있습니다.그러나 데이터 유형, 치수 및 정보를 목록 표현에 저장한 다음 JSON을 사용하여 직렬화할 수 있습니다.
필요한 Import:
import json
import base64
부호화의 경우는, ( )를 사용할 수 있습니다.nparray
는, 의 데이터
json.dumps([str(nparray.dtype), base64.b64encode(nparray), nparray.shape])
그 후에 데이터의 JSON 덤프(문자열)를 얻을 수 있습니다.이 덤프에는 데이터 유형 및 쉐이프, base64로 인코딩된 어레이 데이터/컨텐츠의 리스트가 포함됩니다.
그리고 디코딩을 위해 이것이 작동한다.encStr
는 부호화된 JSON 문자열로, 어딘가에서 로드됩니다).
# get the encoded json dump
enc = json.loads(encStr)
# build the numpy data type
dataType = numpy.dtype(enc[0])
# decode the base64 encoded numpy array data and create a new numpy array with this data & type
dataArray = numpy.frombuffer(base64.decodestring(enc[1]), dataType)
# if the array had more than one data set it has to be reshaped
if len(enc) > 2:
dataArray.reshape(enc[2]) # return the reshaped numpy array containing several data sets
JSON 덤프는 여러 가지 이유로 효율적이고 상호 호환성이 있지만 JSON을 사용하는 것만으로 모든 유형 및 차원의 numpy 어레이를 저장하고 로드하려는 경우 예기치 않은 결과를 초래할 수 있습니다.
이 솔루션에서는 유형이나 치수에 관계없이 Numpy 어레이를 저장 및 로드하고 올바르게 복원(데이터 유형, 치수 등)합니다.
몇 달 전에 몇 가지 솔루션을 직접 사용해 봤는데, 이 솔루션은 제가 접한 유일한 효율적이고 다재다능한 솔루션이었습니다.
Msgpack-numpy의 코드가 도움이 되었습니다.https://github.com/lebedov/msgpack-numpy/blob/master/msgpack_numpy.py
serialized dict를 약간 수정하고 base64 인코딩을 추가하여 serialized size를 줄였습니다.
json과 동일한 인터페이스(load, dump 제공)를 사용함으로써 json 시리얼라이제이션의 드롭인 대체 기능을 제공할 수 있습니다.
이 논리를 확장하여 datetime 객체 등 중요하지 않은 자동 시리얼화를 추가할 수 있습니다.
편집 이 기능을 하는 범용 모듈러 파서를 작성했습니다.https://github.com/someones/jaweson
제 코드는 다음과 같습니다.
np_json.화이
from json import *
import json
import numpy as np
import base64
def to_json(obj):
if isinstance(obj, (np.ndarray, np.generic)):
if isinstance(obj, np.ndarray):
return {
'__ndarray__': base64.b64encode(obj.tostring()),
'dtype': obj.dtype.str,
'shape': obj.shape,
}
elif isinstance(obj, (np.bool_, np.number)):
return {
'__npgeneric__': base64.b64encode(obj.tostring()),
'dtype': obj.dtype.str,
}
if isinstance(obj, set):
return {'__set__': list(obj)}
if isinstance(obj, tuple):
return {'__tuple__': list(obj)}
if isinstance(obj, complex):
return {'__complex__': obj.__repr__()}
# Let the base class default method raise the TypeError
raise TypeError('Unable to serialise object of type {}'.format(type(obj)))
def from_json(obj):
# check for numpy
if isinstance(obj, dict):
if '__ndarray__' in obj:
return np.fromstring(
base64.b64decode(obj['__ndarray__']),
dtype=np.dtype(obj['dtype'])
).reshape(obj['shape'])
if '__npgeneric__' in obj:
return np.fromstring(
base64.b64decode(obj['__npgeneric__']),
dtype=np.dtype(obj['dtype'])
)[0]
if '__set__' in obj:
return set(obj['__set__'])
if '__tuple__' in obj:
return tuple(obj['__tuple__'])
if '__complex__' in obj:
return complex(obj['__complex__'])
return obj
# over-write the load(s)/dump(s) functions
def load(*args, **kwargs):
kwargs['object_hook'] = from_json
return json.load(*args, **kwargs)
def loads(*args, **kwargs):
kwargs['object_hook'] = from_json
return json.loads(*args, **kwargs)
def dump(*args, **kwargs):
kwargs['default'] = to_json
return json.dump(*args, **kwargs)
def dumps(*args, **kwargs):
kwargs['default'] = to_json
return json.dumps(*args, **kwargs)
그러면 다음 작업을 수행할 수 있습니다.
import numpy as np
import np_json as json
np_data = np.zeros((10,10), dtype=np.float32)
new_data = json.loads(json.dumps(np_data))
assert (np_data == new_data).all()
Msgpack은 최고의 시리얼라이제이션 퍼포먼스를 발휘합니다.http://www.benfrederickson.com/dont-pickle-your-data/
msgpack-numpy 를 사용합니다.https://github.com/lebedov/msgpack-numpy 를 참조해 주세요.
인스톨:
pip install msgpack-numpy
그 후, 다음과 같이 입력합니다.
import msgpack
import msgpack_numpy as m
import numpy as np
x = np.random.rand(5)
x_enc = msgpack.packb(x, default=m.encode)
x_rec = msgpack.unpackb(x_enc, object_hook=m.decode)
사용자가 읽을 수 있어야 하고 숫자 배열임을 알고 있는 경우:
import numpy as np;
import json;
a = np.random.normal(size=(50,120,150))
a_reconstructed = np.asarray(json.loads(json.dumps(a.tolist())))
print np.allclose(a,a_reconstructed)
print (a==a_reconstructed).all()
어레이의 사이즈가 커짐에 따라 가장 효율적이지는 않지만, 소규모 어레이에 적합합니다.
@user2357112의 피클 기반 답변을 정리하면 JSON 통합이 쉬워집니다.
다음 코드는 base64로 인코딩됩니다.어떤 타입이나 크기의 numpy 어레이를 처리할 수 있기 때문에, 그 어레이를 기억할 필요는 없습니다.또한 절일 수 있는 다른 임의의 객체도 처리합니다.
import numpy as np
import json
import pickle
import codecs
class PythonObjectEncoder(json.JSONEncoder):
def default(self, obj):
return {
'_type': str(type(obj)),
'value': codecs.encode(pickle.dumps(obj, protocol=pickle.HIGHEST_PROTOCOL), "base64").decode('latin1')
}
class PythonObjectDecoder(json.JSONDecoder):
def __init__(self, *args, **kwargs):
json.JSONDecoder.__init__(self, object_hook=self.object_hook, *args, **kwargs)
def object_hook(self, obj):
if '_type' in obj:
try:
return pickle.loads(codecs.decode(obj['value'].encode('latin1'), "base64"))
except KeyError:
return obj
return obj
# Create arbitrary array
originalNumpyArray = np.random.normal(size=(3, 3))
print(originalNumpyArray)
# Serialization
numpyData = {
"array": originalNumpyArray
}
encodedNumpyData = json.dumps(numpyData, cls=PythonObjectEncoder)
print(encodedNumpyData)
# Deserialization
decodedArrays = json.loads(encodedNumpyData, cls=PythonObjectDecoder)
finalNumpyArray = decodedArrays["array"]
# Verify
print(finalNumpyArray)
print(np.allclose(originalNumpyArray, finalNumpyArray))
print((originalNumpyArray==finalNumpyArray).all())
numpy-serializer를 사용해 보십시오.
다운로드.
pip install numpy-serializer
사용.
import numpy_serializer as ns
import numpy as np
a = np.random.normal(size=(50,120,150))
b = ns.to_bytes(a)
c = ns.from_bytes(b)
assert np.array_equal(a,c)
해라traitschema
https://traitschema.readthedocs.io/en/latest/
"특징과 Numpy를 사용하여 직렬화 가능한 유형 검사 스키마를 만듭니다.일반적인 사용 예에서는 다양한 형태와 유형의 Numpy 어레이를 여러 개 저장할 수 있습니다."
사용해보십시오.numpy.array_repr
또는numpy.array_str
.
언급URL : https://stackoverflow.com/questions/30698004/how-can-i-serialize-a-numpy-array-while-preserving-matrix-dimensions
'programing' 카테고리의 다른 글
JSON 반환이 jquery로 비어 있는지 확인하는 방법 (0) | 2023.04.03 |
---|---|
클라이언트와 서버 간에 비즈니스 로직이 반복되지 않도록 하려면 어떻게 해야 합니까? (0) | 2023.04.03 |
대응 | 페이지 갱신 검출 방법 (F5) (0) | 2023.04.03 |
Boost 속성 트리 write_json이 모든 것을 문자열로 저장하는 이유는 무엇입니까?그것을 변경할 수 있습니까? (0) | 2023.04.03 |
WooCommerce 관리자 주문 대시보드에서 고객 암호 업데이트 (0) | 2023.04.03 |