Создайте разреженную матрицу:
In [38]: M = sparse.random(1000,1000,.2,'csr')
Сохраните ее 3 различными способами:
In [39]: from scipy import io
In [40]: np.savez('Msparse.npz', M=M)
In [41]: sparse.save_npz('M1sparse',M)
In [43]: io.savemat('Msparse.mat', {'M':M})
Размеры файла:
In [47]: ll M1spa* Mspar*
-rw-rw-r-- 1 paul 1773523 Feb 1 12:40 M1sparse.npz
-rw-rw-r-- 1 paul 2404208 Feb 1 12:41 Msparse.mat
-rw-rw-r-- 1 paul 2404801 Feb 1 12:39 Msparse.npz
Загрузите 3 матрицы:
In [48]: M1=sparse.load_npz('M1sparse.npz')
In [49]: M2=np.load('Msparse.npz',allow_pickle=True)['M']
In [50]: M3=io.loadmat('Msparse.mat')['M']
In [51]: M1
Out[51]:
<1000x1000 sparse matrix of type '<class 'numpy.float64'>'
with 200000 stored elements in Compressed Sparse Row format>
In [52]: M2
Out[52]:
array(<1000x1000 sparse matrix of type '<class 'numpy.float64'>'
with 200000 stored elements in Compressed Sparse Row format>,
dtype=object)
In [53]: M3
Out[53]:
<1000x1000 sparse matrix of type '<class 'numpy.float64'>'
with 200000 stored elements in Compressed Sparse Column format>
M1
и M3
одинаковы - csr
как M
для save_npz
, csc
(формат MATLAB) для .mat
.
M2
имеет объектную обертку dtype.
In [54]: (M1*np.ones((1000,1))).shape
Out[54]: (1000, 1)
In [55]: (M3*np.ones((1000,1))).shape
Out[55]: (1000, 1)
Это заняло намного больше времени; и я почти не смею смотреть на результат.
In [56]: (M2*np.ones((1000,1))).shape
Out[56]: (1000, 1)
Если я извлекаю матрицу из массива объектов, умножение происходит быстро
In [57]: (M2.item()*np.ones((1000,1))).shape
Out[57]: (1000, 1)
In [58]: (M2.item()*np.ones((1000,1))).dtype
Out[58]: dtype('float64')
In [59]: (M3*np.ones((1000,1))).dtype
Out[59]: dtype('float64')
Если присмотреться к M2
умножение:
In [60]: (M2*np.ones((1000,1))).dtype
Out[60]: dtype('O')
In [61]: (M2*np.ones((1000,1)))[:2,:]
Out[61]:
array([[<1000x1000 sparse matrix of type '<class 'numpy.float64'>'
with 200000 stored elements in Compressed Sparse Row format>],
[<1000x1000 sparse matrix of type '<class 'numpy.float64'>'
with 200000 stored elements in Compressed Sparse Row format>]],
dtype=object)
Выполняет умножение M*1
для каждого элемента ones
- создание 1000 разреженных матриц. Вот куда уходит потребление вашей памяти.
В итоге, при использовании savez
он оборачивает каждую разреженную матрицу в массив dtype объекта и выполняет выборку. Поэтому вы не должны использовать `data ['Dx'] напрямую
Dx = data['Dx'] # wrong
Dx = data['Dx'].item() # right