документация по преобразованию матрицы scipy неясна

#python #numpy #scipy #sparse-matrix

Вопрос:

Я конвертирую dok в матрицу coo в scipy, и документация кажется мне неясной. Моя цель-не разрушить исходную матрицу! В документации говорится:

Преобразуйте эту матрицу в сжатый формат разреженных строк. При значении copy=False данные/индексы могут быть разделены между этой матрицей и результирующей csr_matrix.

Однако, похоже, он выводит матрицу, а не преобразует исходную. Я думал, что «копирование» может изменить поведение от преобразования к созданию копии, но тестирование показывает, что это не может быть правдой. Моя программа работает долго, поэтому я не хочу случайно уничтожать матрицу прямо перед ее экспортом 🙂

 mat = scipy.sparse.dok_matrix((10,10),dtype=np.int16) type(mat)  

lt;класс ‘scipy.sparse.dok.dok_matrix’gt;

 coo = mat.tocoo(copy=True) print(type(mat))  

lt;класс ‘scipy.sparse.dok.dok_matrix’gt;

 print(type(coo))  

lt;класс ‘scipy.sparse.coo.coo_matrix’gt;

 coo = mat.tocoo(copy=False) print(type(mat))  

lt;класс ‘scipy.sparse.dok.dok_matrix’gt;

 print(type(coo))  

lt;класс ‘scipy.sparse.coo.coo_matrix’gt;

Спасибо!

Комментарии:

1. Объект matrix относится к массивам, которые содержат ненулевые записи матрицы, расположение этих записей и т.д. Я думаю, что копирование определяет, копируются ли эти другие массивы или обе матрицы, где это возможно, ссылаются на одни и те же базовые массивы. Попробуйте сменить коврик. данные в ваших экспериментах для одной матрицы и посмотрите, влияет ли это на мат. данные в другой матрице

Ответ №1:

Вам не нужно беспокоиться об этом, у dok.tocoo вас всегда будет копия. Кроме того, подобные методы всегда возвращают новую матрицу; они не работают на месте. Совместное использование применяется к базовым структурам данных, в которых хранятся значения и индексы, любые, только если они достаточно похожи.

Базовая структура данных для a dok -это a dict , для coo 3 массивов numpy. Невозможно выполнить преобразование без копирования данных.

Они небрежно обращаются с документацией здесь, просто копируя ее из общего шаблона. copy Параметр имеет значение при выполнении «преобразования того же типа», например dok.todok() , или a coo.tocoo() . Но приложение в разных форматах почти всегда будет копией — я использую «почти», потому что не уверен в некоторых подобных csr.tocsc .

Если вы пишете функцию, которая принимает разреженную матрицу любого формата, и вам необходимо убедиться, что это , скажем, coo так, вы можете захотеть использовать

 M1 = M.tocoo(copy=True)  

чтобы гарантировать , что какие-либо изменения M1 не появятся M , даже если M они уже coo были .


Ваша цитата была из tocsr А. Фактический код для этой dok версии таков

 self.tocoo(copy=copy).tocsr(copy=False)  

сначала dok он преобразуется в общий coo формат, а оттуда в csr (или в один из других).

Код для dok.tocoo этого:

 def tocoo(self, copy=False):  from .coo import coo_matrix  if self.nnz == 0:  return coo_matrix(self.shape, dtype=self.dtype)   idx_dtype = get_index_dtype(maxval=max(self.shape))  data = np.fromiter(self.values(), dtype=self.dtype, count=self.nnz)  row = np.fromiter((i for i, _ in self.keys()), dtype=idx_dtype, count=self.nnz)  col = np.fromiter((j for _, j in self.keys()), dtype=idx_dtype, count=self.nnz)  A = coo_matrix((data, (row, col)), shape=self.shape, dtype=self.dtype)  A.has_canonical_format = True  return A