Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/361.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 将scipy稀疏矩阵存储为HDF5_Python_Scipy_Sparse Matrix_Hdf5_H5py - Fatal编程技术网

Python 将scipy稀疏矩阵存储为HDF5

Python 将scipy稀疏矩阵存储为HDF5,python,scipy,sparse-matrix,hdf5,h5py,Python,Scipy,Sparse Matrix,Hdf5,H5py,我想用HDF5格式压缩并存储一个庞大的Scipy矩阵。我该怎么做?我尝试了以下代码: a = csr_matrix((dat, (row, col)), shape=(947969, 36039)) f = h5py.File('foo.h5','w') dset = f.create_dataset("init", data=a, dtype = int, compression='gzip') 我会犯这样的错误 TypeError: Scalar datasets don't su

我想用HDF5格式压缩并存储一个庞大的Scipy矩阵。我该怎么做?我尝试了以下代码:

a = csr_matrix((dat, (row, col)), shape=(947969, 36039))
f = h5py.File('foo.h5','w')    
dset = f.create_dataset("init", data=a, dtype = int, compression='gzip')
我会犯这样的错误

TypeError: Scalar datasets don't support chunk/filter options
IOError: Can't prepare for writing data (No appropriate function for conversion path)
我无法将其转换为numpy数组,因为将出现内存溢出。最好的方法是什么?

你可以使用这个方法

可选地考虑使用,但请注意,该方法是<强>非常慢< /强>(谢谢)

演示:

生成稀疏矩阵和稀疏帧

In [55]: import pandas as pd

In [56]: from scipy.sparse import *

In [57]: m = csr_matrix((20, 10), dtype=np.int8)

In [58]: m
Out[58]:
<20x10 sparse matrix of type '<class 'numpy.int8'>'
        with 0 stored elements in Compressed Sparse Row format>

In [59]: sdf = pd.SparseDataFrame([pd.SparseSeries(m[i].toarray().ravel(), fill_value=0)
    ...:                           for i in np.arange(m.shape[0])])
    ...:

In [61]: type(sdf)
Out[61]: pandas.sparse.frame.SparseDataFrame

In [62]: sdf.info()
<class 'pandas.sparse.frame.SparseDataFrame'>
RangeIndex: 20 entries, 0 to 19
Data columns (total 10 columns):
0    20 non-null int8
1    20 non-null int8
2    20 non-null int8
3    20 non-null int8
4    20 non-null int8
5    20 non-null int8
6    20 non-null int8
7    20 non-null int8
8    20 non-null int8
9    20 non-null int8
dtypes: int8(10)
memory usage: 280.0 bytes
从HDF文件读取

In [65]: store = pd.HDFStore('d:/temp/sparse_df.h5')

In [66]: store
Out[66]:
<class 'pandas.io.pytables.HDFStore'>
File path: d:/temp/sparse_df.h5
/sparse_df            sparse_frame

In [67]: x = store['sparse_df']

In [68]: type(x)
Out[68]: pandas.sparse.frame.SparseDataFrame

In [69]: x.info()
<class 'pandas.sparse.frame.SparseDataFrame'>
Int64Index: 20 entries, 0 to 19
Data columns (total 10 columns):
0    20 non-null int8
1    20 non-null int8
2    20 non-null int8
3    20 non-null int8
4    20 non-null int8
5    20 non-null int8
6    20 non-null int8
7    20 non-null int8
8    20 non-null int8
9    20 non-null int8
dtypes: int8(10)
memory usage: 360.0 bytes
[65]中的
:store=pd.HDFStore('d:/temp/sparse_df.h5'))
在[66]中:商店
出[66]:
文件路径:d:/temp/sparse_df.h5
/稀疏帧
在[67]中:x=store['sparse_df']
In[68]:类型(x)
Out[68]:pandas.sparse.frame.sparaframe
在[69]:x.info()中
INT64索引:20个条目,0到19
数据列(共10列):
0 20非空int8
120非空int8
2 20非空int8
3 20非空int8
4 20非空int8
5 20非空int8
6 20非空int8
7 20非空int8
8 20非空int8
9 20非空int8
数据类型:int8(10)
内存使用:360.0字节

csr矩阵将其值存储在3个数组中。它不是数组或数组子类,因此
h5py
无法直接保存它。您最好保存属性,并在加载时重新创建矩阵:

In [248]: M = sparse.random(5,10,.1, 'csr')
In [249]: M
Out[249]: 
<5x10 sparse matrix of type '<class 'numpy.float64'>'
    with 5 stored elements in Compressed Sparse Row format>
In [250]: M.data
Out[250]: array([ 0.91615298,  0.49907752,  0.09197862,  0.90442401,  0.93772772])
In [251]: M.indptr
Out[251]: array([0, 0, 1, 2, 3, 5], dtype=int32)
In [252]: M.indices
Out[252]: array([5, 7, 5, 2, 6], dtype=int32)
In [253]: M.data
Out[253]: array([ 0.91615298,  0.49907752,  0.09197862,  0.90442401,  0.93772772])
新的
save\u npz
功能可以:

arrays_dict = dict(format=matrix.format, shape=matrix.shape, data=matrix.data)
if matrix.format in ('csc', 'csr', 'bsr'):
    arrays_dict.update(indices=matrix.indices, indptr=matrix.indptr)
...
elif matrix.format == 'coo':
    arrays_dict.update(row=matrix.row, col=matrix.col)
...
np.savez(file, **arrays_dict)
换句话说,它收集字典中的相关属性,并使用
savez
创建zip存档

同样的方法可用于
h5py
文件。在最近的一个SO问题中,有关于
save_npz
的更多信息,并有到源代码的链接

看看你能不能让它工作。如果可以创建
csr
矩阵,则可以从其属性(或
coo
等价物)重新创建该矩阵。如果需要,我可以做一个有效的例子

csr到h5py示例 生产

1314:~/mypy$ python3 stack43390038.py 
<10x10 sparse matrix of type '<class 'numpy.float64'>'
    with 20 stored elements in Compressed Sparse Row format>
[ 0.13640389  0.92698959 ....  0.7762265 ]
[4 5 0 3 0 2 0 2 5 6 7 1 7 9 1 3 4 6 8 9]
[ 0  2  4  6  9 11 11 11 14 19 20]
['Mcsr']
['data', 'indices', 'indptr']
[10 10]
<10x10 sparse matrix of type '<class 'numpy.float64'>'
    with 20 stored elements in Compressed Sparse Row format>
True

您需要保存矩阵的数据属性,而不是矩阵本身
a
不是numpy数组或子类。首先,只需保存输入
dat
行,
。最近的一个
scipy.sparse`版本有一个
save_npz
函数,可以作为一个模型-看看它的代码。最近关于
save_npz
的问题,你的样本矩阵的可能副本有0个非零元素。np.arange(m.shape[0])中的i的迭代表达式,
[pd.SparseSeries(m[i].toarray().ravel(),fill_value=0)
对于大型矩阵来说速度会非常慢。@hpaulj,感谢您的评论!我要去考试it@hpaulj,是的-速度非常慢-我用稀疏矩阵测试了它:
M=sparse.random(10**4,10**3,01,'csr')
-需要
1分钟2秒
,所以对于OPs矩阵来说需要更长的时间。不幸的是,我无法使它更快…这个答案以“您可以使用scipy.sparse.save_npz方法”开头,但从未解释如何使用此方法保存到HDF5。据我所知,该方法保存到一个扩展名为“.npz”的常规文件中。非常好!我认为,如果您能添加一个小片段来保存HDF格式的稀疏矩阵,那将非常有帮助。非常感谢。在上一个示例中,我将
g2['data']
数据集传递给
coo_matrix
函数,但该函数将
np.array(obj,…)
应用于加载数据的输入。所以,不,你不能在没有加载的情况下创建矩阵。谢谢!我有一些最大的稀疏数组,我正在尝试更快地加载,但似乎要避免复制数组需要做太多的工作。
arrays_dict = dict(format=matrix.format, shape=matrix.shape, data=matrix.data)
if matrix.format in ('csc', 'csr', 'bsr'):
    arrays_dict.update(indices=matrix.indices, indptr=matrix.indptr)
...
elif matrix.format == 'coo':
    arrays_dict.update(row=matrix.row, col=matrix.col)
...
np.savez(file, **arrays_dict)
import numpy as np
import h5py
from scipy import sparse

M = sparse.random(10,10,.2, 'csr')
print(repr(M))

print(M.data)
print(M.indices)
print(M.indptr)

f = h5py.File('sparse.h5','w')
g = f.create_group('Mcsr')
g.create_dataset('data',data=M.data)
g.create_dataset('indptr',data=M.indptr)
g.create_dataset('indices',data=M.indices)
g.attrs['shape'] = M.shape
f.close()

f = h5py.File('sparse.h5','r')
print(list(f.keys()))
print(list(f['Mcsr'].keys()))

g2 = f['Mcsr']
print(g2.attrs['shape'])

M1 = sparse.csr_matrix((g2['data'][:],g2['indices'][:],
    g2['indptr'][:]), g2.attrs['shape'])
print(repr(M1))
print(np.allclose(M1.A, M.A))
f.close()
1314:~/mypy$ python3 stack43390038.py 
<10x10 sparse matrix of type '<class 'numpy.float64'>'
    with 20 stored elements in Compressed Sparse Row format>
[ 0.13640389  0.92698959 ....  0.7762265 ]
[4 5 0 3 0 2 0 2 5 6 7 1 7 9 1 3 4 6 8 9]
[ 0  2  4  6  9 11 11 11 14 19 20]
['Mcsr']
['data', 'indices', 'indptr']
[10 10]
<10x10 sparse matrix of type '<class 'numpy.float64'>'
    with 20 stored elements in Compressed Sparse Row format>
True
Mo = M.tocoo()
g = f.create_group('Mcoo')
g.create_dataset('data', data=Mo.data)
g.create_dataset('row', data=Mo.row)
g.create_dataset('col', data=Mo.col)
g.attrs['shape'] = Mo.shape

g2 = f['Mcoo']
M2 = sparse.coo_matrix((g2['data'], (g2['row'], g2['col'])),
   g2.attrs['shape'])   # don't need the [:]
# could also use sparse.csr_matrix or M2.tocsr()