4

numpyJsonでダンプしたい配列があります。配列は次のようになります。

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

そして私はそれを次のようにJsonで文字列にダンプしたいと思います:

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

私は試しました:

import jason
my_string = json.dumps(my_array)

しかし、それは不平を言います:

"not JSON serializable"

これをJsonで文字列にダンプする方法について何か考えはありますか?

アップデート:

注文は気にしないでください。行は次の順序で印刷する必要があります。

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

5 に答える 5

7

float64の1024x1002配列が大きいので、私にとってうまくいったのはbase64への変換でした。

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の結果はbase64を非常に明確に示しています。

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
于 2013-10-09T11:54:30.363 に答える
1

JSONのシリアル化可能な部分についてはよくわかりませんが、最初にdictに変換できますか?これはJSON出力のより自然な形式のようであり、データ型に関する問題に対処します。

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

于 2012-11-19T21:04:48.347 に答える
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}'
于 2012-11-19T21:05:31.763 に答える
0

配列のきれいな文字列表現を取得しようとしていて、文字列配列型を使用しても目的の表現が得られない場合は、メッセージのシリアル化形式を使用する必要はありません。シリアル化フォーマットは、データを保存/送信するためのものです。Jsonは、人間が読める形式であることが多いという点で優れていますが、それは目的ではなく、別の形式に強制すると、jsonのシリアル化ではなくなります。savetxtおよびloadtxtnumpyオプションでさえ、必要なフォーマットでは機能しません(各列の最初の行を繰り返します)。次のコードを使用して、その形式にする必要がある場合は、独自のシリアル化を行うことができます。

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と配列形状を含むタプルに変換します。

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

したがって、dumpsおよびloadsコマンドは次のようになります。

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

また、これはmsgpack.dumpsおよびmsgpack.loads(より高速でよりコンパクトなバイナリ表現)でも機能します。

配列に適用される可能性のある警告:numpy配列がオブジェクトdtypeの場合、標準メソッドでは完全配列としてシリアル化されません。配列に格納されているのはデータではなくオブジェクトIDであるため、各オブジェクトを個別にシリアル化する必要があります。dtypeをdtype='|S'として使用します。ここで、は最大文字列長であり、配列はシリアル化可能になります。

于 2012-11-19T22:37:56.897 に答える
-1

私はnumpyを少しだけ使用しましたが、データを特別な形式で内部的に保存すると思うので、jsonモジュールがそれを処理する方法を知らないのは理にかなっています。

配列に戻すことはできますか?

json.dumps(numpy.asarray(my_array))

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

于 2012-11-19T21:03:14.880 に答える