2012-11-19 2 views
3

나는 numpy 배열을 가지고 있으며 Json으로 덤프하려고합니다.Json을 사용하여 2D 파이썬 배열 덤프

array([['foo', 'bar', 'something', ... 
     'more'], 
     ['0.4', '0.7', '0.83', ... 
     '0.3', '0.62', '0.51']] 

다음과 같이 내가 JSON와 문자열 에 덤프 싶습니다 : : 배열은 다음과 같습니다

import jason 
my_string = json.dumps(my_array) 

하지만 :

foo: 0.4 
bar: 0.7 
something: 0.51 
... 

내가 함께 시도 그것으로 불평한다 :

"not JSON serializable" 

문자열에 이것을 덤프하는 방법에 대한 의견이 있으시면 with Json?

는 업데이트 :

하지 내가 선이 다음과 같은 순서로 인쇄되어야 주문에 대한 관심이 있음을하시기 바랍니다 :

array[0,0] : array[0,1] 
array[1,0] : array[1,1] 
array[2,0] : array[2,1] 
# etc ... 
+0

배열 색인이 올바르지 않습니다. 이것과 같은 2D 배열의 경우 구문은'array [row] [column]'이고 두 행만 있기 때문에 첫 번째 인덱스의 최대 값은'1'이됩니다. – martineau

답변

6

float64의 1024x1002 배열이 더 크기 때문에 - base64로 변환되었습니다. 매우 명확베이스 64에

def Base64Encode(ndarray): 
    return json.dumps([str(ndarray.dtype),base64.b64encode(ndarray),ndarray.shape]) 
def Base64Decode(jsonDump): 
    loaded = json.loads(jsonDump) 
    dtype = np.dtype(loaded[0]) 
    arr = np.frombuffer(base64.decodestring(loaded[1]),dtype) 
    if len(loaded) > 2: 
     return arr.reshape(loaded[2]) 
    return arr 

''' just to compare ''' 
def SimpleEncode(ndarray): 
    return json.dumps(ndarray.tolist()) 
def SimpleDecode(jsonDump): 
    return np.array(json.loads(jsonDump)) 

ipython % timeit 결과 포인트 :

arr = np.random.random_sample((1000, 1000)) 

print 'Simple Convert' 
%timeit SimpleDecode(SimpleEncode(arr)) 
print 'Base64 Encoding' 
%timeit Base64Decode(Base64Encode(arr)) 

결과 : 마지막에

Simple Convert 
1 loops, best of 3: 1.42 s per loop 
Base64 Encoding 
10 loops, best of 3: 171 ms per loop 
0

난 단지 NumPy와 약간의와 함께 일했지만, 내 생각은 데이터를 저장 내부적으로는 특별한 형식으로되어 있기 때문에 json 모듈은 어떻게 처리해야할지 모른다.

다시 배열로 변환합니까?

JSON 직렬화 부분에 대해 확실
json.dumps(numpy.asarray(my_array)) 

http://docs.scipy.org/doc/numpy/reference/generated/numpy.asarray.html

1

하지 ,하지만 당신은 먼저 DICT로 변환 할 수 있을까? 이는 JSON 출력용으로 더 자연스러운 형식처럼 보이고 데이터 유형의 모든 문제를 처리합니다. 모든 값이 숫자 인 경우 모든 다른 실패하면

my_dict = dict(zip(my_array[1], my_array[0]))

+0

배열에있는 순서를 유지합니까? (예 :'my_array [0,0] : my_array [0,1]''my_array [1,0] : my_array [1,1]'행 앞에 인쇄해야합니다.) –

+0

그러나 사전은 키를 유지합니다 이 값을 JSON에 전달할 때 내 사전의 항목이 올바른 순서로 인쇄된다는 것을 어떻게 보장합니까? –

+0

아마 그렇지 않을 수 있습니다. 아마도이 기능이 작동하지 않을 수 있습니다 .Python dicts는 기본적으로 순서가 지정되어 있지 않습니다. 2.7에는 OrderedDict 클래스가 있지만 작동 여부는 JSON 라이브러리가 순서를 존중하는지 여부에 달려 있습니다 (이전에 삭제 한 이전 주석에서 응답 한 것으로 나타났습니다.) 주석을 철저히 읽지 전에 대답했습니다. 새로운 여기, 미안.) –

0

, 당신은 항상 수동으로 작업을 수행 할 수 있습니다

my_array = [['0.4', '0.7', '0.83', '0.3', '0.62', '0.51'], 
      ['foo', 'bar', 'something', 'more']] 

pairs = zip(my_array[1], my_array[0]) 
json_values = ('"{}": {}'.format(label, value) for label, value in pairs) 
my_string = '{' + ', '.join(json_values) + '}' 

print my_string # '{"foo": 0.4, "bar": 0.7, "something": 0.83, "more": 0.3}' 
0

당신이 당신의 배열의 귀여운 캐릭터 라인 표현을 얻으려고 노력하고 사용하는 경우 문자열 배열 유형이 원하는 표현을 제공하지 않으면 메시지 직렬화 형식이 사용할 것이 아닙니다. 직렬화 형식은 데이터 저장/전송을위한 형식입니다. Json은 사람이 읽기 쉽기 때문에 멋지지만 좋은 목적이 아니며이를 다른 형식으로 강요하면 더 이상 json serialization이되지 않습니다. savetxt 및 loadtxt numpy 옵션조차도 원하는 형식 (각 열의 첫 번째 행 반복)에 대해 작동하지 않습니다. 그것은 다음과 같은 코드를 사용하여 해당 형식에있을 경우 당신은 당신의 자신의 직렬화를 만들 수 있습니다

def prettySerialize(inArray): 
    ids = inArray[0] 
    strRep = '' 

    for row in inArray[1:]: 
     for i,item in enumerate(row): 
      rowStr = id[i] + ':' + item + '\n' 
      strRep += rowStr 

    return strRep 
이의 문제가 훨씬 느리게하고 "ID를 반복 배열의 훨씬 더 큰 표현 (될 것입니다

"행 반복해서). 인간의 독서를 위해 특별히 서식을 지정하지 않는 한 순수한 json (또는 msgpack) 솔루션을 사용하는 것이 좋습니다 ...

이 메시지는 msgpack (json에서도 작동)과 함께 사용하는 솔루션입니다. ..DTYPE 및 배열 형태를 포함하는 튜플로 변환 :

strRep = json.dumps(arrayToTuple(arr)) 
arrayFromTuple(json.loads(strRep)) 

그리고 이것은 또한 빠른 이상 (msgpack.dumps 및 msgpack.loads 작동 :

def arrayToTuple(arr): 
    if arr is None: 
     return None 

    return (arr.dtype.str, arr.shape, arr.tostring()) 

def arrayFromTuple(tupl): 
    if tupl is None: 
     return None 

    typeStr, shape, dataStr = tupl 

    resultArray = numpy.fromstring(dataStr, dtype=typeStr).reshape(shape) 

    return resultArray 

그래서 덤프 및로드 명령이 될 것이다 컴팩트 한 2 진 표현).

배열에 적용 가능한주의 사항 : numpy 배열이 dtype 객체 인 경우 표준 배열로 전체 배열로 직렬화되지 않습니다. 배열에 저장된 데이터가 아닌 객체 ID이기 때문에 각 객체를 개별적으로 직렬화해야합니다. dtype을 dtype = '| S'로 사용하면 최대 문자열 길이는 배열을 직렬화 할 수 있습니다.