10

以前に保存したスパース配列を読み込もうとしています。スパース配列の保存は簡単でした。それを読もうとするのは苦痛ですが。scipy.loadは、スパース配列の周りに0d配列を返します。

import scipy as sp
A = sp.load("my_array"); A
array(<325729x325729 sparse matrix of type '<type 'numpy.int8'>'
with 1497134 stored elements in Compressed Sparse Row format>, dtype=object)

スパース行列を取得するには、0d配列をフラット化するか、sp.asarray(A)を使用する必要があります。これは物事を行うのに本当に難しい方法のようです。Scipyは、スパース配列をロードしたことを理解するのに十分賢いですか?スパース配列をロードするためのより良い方法はありますか?

4

3 に答える 3

15

scipy.ioのmmwrite / mmread関数は、マトリックス マーケット形式でスパース マトリックスを保存/ロードできます。

scipy.io.mmwrite('/tmp/my_array',x)
scipy.io.mmread('/tmp/my_array').tolil()    

mmwriteそして、mmreadあなたが必要とするすべてかもしれません。これは十分にテストされており、よく知られている形式を使用しています。

ただし、次の場合は少し高速になる可能性があります。

行と列の座標とデータを npz 形式の 1 次元配列として保存できます。

import random
import scipy.sparse as sparse
import scipy.io
import numpy as np

def save_sparse_matrix(filename,x):
    x_coo=x.tocoo()
    row=x_coo.row
    col=x_coo.col
    data=x_coo.data
    shape=x_coo.shape
    np.savez(filename,row=row,col=col,data=data,shape=shape)

def load_sparse_matrix(filename):
    y=np.load(filename)
    z=sparse.coo_matrix((y['data'],(y['row'],y['col'])),shape=y['shape'])
    return z

N=20000
x = sparse.lil_matrix( (N,N) )
for i in xrange(N):
    x[random.randint(0,N-1),random.randint(0,N-1)]=random.randint(1,100)

save_sparse_matrix('/tmp/my_array',x)
load_sparse_matrix('/tmp/my_array.npz').tolil()

以下は、mmwrite/mmread を使用するよりもスパース行列を npz ファイルに保存する方が速い可能性があることを示唆するコードです。

def using_np_savez():    
    save_sparse_matrix('/tmp/my_array',x)
    return load_sparse_matrix('/tmp/my_array.npz').tolil()

def using_mm():
    scipy.io.mmwrite('/tmp/my_array',x)
    return scipy.io.mmread('/tmp/my_array').tolil()    

if __name__=='__main__':
    for func in (using_np_savez,using_mm):
        y=func()
        print(repr(y))
        assert(x.shape==y.shape)
        assert(x.dtype==y.dtype)
        assert(x.__class__==y.__class__)    
        assert(np.allclose(x.todense(),y.todense()))

収量

% python -mtimeit -s'import test' 'test.using_mm()'
10 loops, best of 3: 380 msec per loop

% python -mtimeit -s'import test' 'test.using_np_savez()'
10 loops, best of 3: 116 msec per loop
于 2011-06-08T18:53:12.673 に答える
6

() をインデックスとして使用して、0d 配列に隠されているオブジェクトを抽出できます。

A = sp.load("my_array")[()]

これは奇妙に見えますが、とにかくうまくいくようで、非常に短い回避策です。

于 2015-03-25T16:48:44.137 に答える