Построение большой разреженной матрицы scipy

#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 матрицу из блоков, также будет поучительным.