매트릭스 치수를 유지하면서 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 |