print make data python numpy scipy hdf5 pytables

python - make - Almacenamiento de la matriz numpy dispersa en HDF5(PyTables)



show table python (3)

He actualizado la excelente respuesta de Pietro Battiston para Python 3.6 y PyTables 3.x, ya que algunos nombres de funciones de PyTables han cambiado en la actualización de 2.x.

import numpy as np from scipy import sparse import tables def store_sparse_mat(M, name, filename=''store.h5''): """ Store a csr matrix in HDF5 Parameters ---------- M : scipy.sparse.csr.csr_matrix sparse matrix to be stored name: str node prefix in HDF5 hierarchy filename: str HDF5 filename """ assert(M.__class__ == sparse.csr.csr_matrix), ''M must be a csr matrix'' with tables.open_file(filename, ''a'') as f: for attribute in (''data'', ''indices'', ''indptr'', ''shape''): full_name = f''{name}_{attribute}'' # remove existing nodes try: n = getattr(f.root, full_name) n._f_remove() except AttributeError: pass # add nodes arr = np.array(getattr(M, attribute)) atom = tables.Atom.from_dtype(arr.dtype) ds = f.create_carray(f.root, full_name, atom, arr.shape) ds[:] = arr def load_sparse_mat(name, filename=''store.h5''): """ Load a csr matrix from HDF5 Parameters ---------- name: str node prefix in HDF5 hierarchy filename: str HDF5 filename Returns ---------- M : scipy.sparse.csr.csr_matrix loaded sparse matrix """ with tables.open_file(filename) as f: # get nodes attributes = [] for attribute in (''data'', ''indices'', ''indptr'', ''shape''): attributes.append(getattr(f.root, f''{name}_{attribute}'').read()) # construct sparse matrix M = sparse.csr_matrix(tuple(attributes[:3]), shape=attributes[3]) return M

Tengo problemas para almacenar una csr_matrix numpy con PyTables. Me aparece este error:

TypeError: objects of type ``csr_matrix`` are not supported in this context, sorry; supported objects are: NumPy array, record or scalar; homogeneous list or tuple, integer, float, complex or string

Mi código:

f = tables.openFile(path,''w'') atom = tables.Atom.from_dtype(self.count_vector.dtype) ds = f.createCArray(f.root, ''count'', atom, self.count_vector.shape) ds[:] = self.count_vector f.close()

¿Algunas ideas?

Gracias


La respuesta de DaveP es casi correcta ... pero puede causar problemas en matrices muy dispersas: si la (s) última (s) columna (s) o fila (s) están vacías, se descartan. Entonces, para estar seguro de que todo funciona, también se debe almacenar el atributo "forma".

Este es el código que uso regularmente:

import tables as tb from numpy import array from scipy import sparse def store_sparse_mat(m, name, store=''store.h5''): msg = "This code only works for csr matrices" assert(m.__class__ == sparse.csr.csr_matrix), msg with tb.openFile(store,''a'') as f: for par in (''data'', ''indices'', ''indptr'', ''shape''): full_name = ''%s_%s'' % (name, par) try: n = getattr(f.root, full_name) n._f_remove() except AttributeError: pass arr = array(getattr(m, par)) atom = tb.Atom.from_dtype(arr.dtype) ds = f.createCArray(f.root, full_name, atom, arr.shape) ds[:] = arr def load_sparse_mat(name, store=''store.h5''): with tb.openFile(store) as f: pars = [] for par in (''data'', ''indices'', ''indptr'', ''shape''): pars.append(getattr(f.root, ''%s_%s'' % (name, par)).read()) m = sparse.csr_matrix(tuple(pars[:3]), shape=pars[3]) return m

Es trivial adaptarlo a matrices csc.


Una matriz de CSR se puede reconstruir completamente a partir de sus data , indices y atributos indptr . Estas son solo matrices numpy regulares, por lo que no debería haber ningún problema al almacenarlas como 3 matrices separadas en tablas piramidales, y luego pasarlas al constructor de csr_matrix . Mira los documentos impertinentes .

Editar: La respuesta de Pietro ha señalado que el miembro de shape también debe ser almacenado