#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