#scipy #sparse-matrix
#scipy #разреженная матрица
Вопрос:
Один из лучших способов построения разреженной матрицы scipy — это метод coo_matrix ie.
coo_matrix((data, (i, j)), [shape=(M, N)])
where:
data[:] are the entries of the matrix, in any order
i[:] are the row indices of the matrix entries
j[:] are the column indices of the matrix entries
Но, если матрица очень большая, нецелесообразно загружать все i, j и векторы данных в память.
Как вы создаете coo_matrix таким образом, чтобы (данные, (i, j)) загружались (с помощью итератора или генератора) с диска, а объекты массива / вектора на диске были либо в .npy, либо в форматах pickle?
Pickle — лучший вариант, поскольку numpy.save / load не оптимизированы для scipy sparse. Может быть, есть другой более быстрый формат.
Оба numpy.genfromtext() и numpy.loadtxt() являются громоздкими, медленными и требуют много памяти.
Ответ №1:
Я не совсем понимаю. Если i, j, data
массивы слишком велики для создания или загрузки в память, то они слишком велики для создания разреженной матрицы.
Если эти три массива допустимы, результирующая разреженная матрица будет использовать их без копирования или изменения в качестве соответствующих атрибутов. csr
Матрица, построенная из coo
, может быть немного более компактной, поскольку ее indptr
массив имеет одно значение на строку. Массивы data
and indices
будут того же размера, coo
что и (дают или принимают заданные дубликаты и сортировку).
dok
и lil
форматы могут использоваться для создания инкрементной матрицы, но они не будут экономить память в долгосрочной перспективе. Обе по-прежнему должны иметь запись для каждой ненулевой точки данных. В этом lil
случае у вас будет куча списков; в то время dok
как это фактический словарь.
Ни один из разреженных форматов не является «виртуальным», создавая элементы «на лету» по мере необходимости.
Я не понимаю, как различные методы загрузки 3 определяющих массива помогают, если их общий размер слишком велик.
In [782]: data=np.ones((10,),int)
In [783]: rows=np.arange(10)
In [784]: cols=np.arange(10)
In [785]: M=sparse.coo_matrix((data,(rows,cols)))
In [786]: M.data
Out[786]: array([1, 1, 1, 1, 1, 1, 1, 1, 1, 1])
In [787]: M.data is data
Out[787]: True
In [789]: M.col is cols
Out[789]: True
По сути coo
, формат — это способ хранения этих 3 массивов. Реальная работа, вся математика, суммирование, даже индексация, выполняется с csr
форматом.
Комментарии:
1. Используя ваш пример для создания coo_matrix, память содержит данные объектов, строки, столбцы и M. Вопрос в том, можно ли создавать coo_matrix постепенно с потоковыми строками, ссылками и данными. Ваш ответ предполагает, что это невозможно.
2.
__init__
Код дляcoo_matrix
написан на Python и прост в использовании. Код дляbmat
, который строитcoo
матрицу из блоков, также будет поучительным.