Scipy 使用非 int64 (indptr, indices) 为点构建的稀疏矩阵

Scipy Sparse Matrix built with non-int64 (indptr, indices) for dot

手动构造scipy.sparse.csr_matrix时,indptr和indices可以使用uint32类型吗?矩阵的点法return会是正确答案吗?

下面的例子好像没问题。。。不知道官方是不是这样。

import numpy as np
import scipy.sparse as spsp
x = np.random.choice([0,1],size=(1000,1000), replace=True, p=[0.9,0.1])
x = x.astype(np.uint8)

x_csr = spsp.csr_matrix(x)
x_csr.indptr = x_csr.indptr.astype(np.uint32)
x_csr.indices = x_csr.indices.astype(np.uint32)

x_csr_selfdot = x_csr.dot(x_csr.T)
x_selfdot = x.dot(x.T)

print(np.sum(x_selfdot != x_csr_selfdot))

x_csr.data 是 1 的数组。Scipy 不允许我使用单个数字来替换整个 x_csr.data 数组。

我不确定你的目标是什么。你所做的工作(有点)

In [237]: X=x_csr.dot(x_csr.T)

In [238]: np.allclose(X.A,x.dot(x.T))
Out[238]: True

也就是说,与修改后的 x_csr 的乘法有效。

但请注意,对 x_csr 的任何操作都会使索引

恢复为 int32 以创建新的稀疏矩阵
In [240]: x_csr.indptr
Out[240]: array([    0,   112,   216, ..., 99652, 99751, 99853], dtype=uint32)

In [241]: x_csr.T.indptr
Out[241]: array([    0,   112,   216, ..., 99652, 99751, 99853], dtype=int32)

In [242]: X.indptr
Out[242]: array([     0,   1000,   2000, ..., 997962, 998962, 999962], dtype=int32)

In [260]: x_csr[:].indptr
Out[260]: array([    0,   112,   216, ..., 99652, 99751, 99853], dtype=int32)

.data 的 dtype 被保留,但在创建新矩阵时,sparse 会创建自己的 indptrindices 数组。它不会尝试查看原件。

是的,data 属性必须为矩阵的每个非零元素指定一个值。所以 dataindices 的大小相同。在 coo 格式中,rowcol 也匹配 data.

另外 print(x_csr)x_csr.tocoo():

时给出错误
--> 931         _sparsetools.expandptr(major_dim,self.indptr,major_indices)
ValueError: Output dtype not compatible with inputs.

一般情况下,不要尝试去玩csr矩阵的indicesindptr。让 sparse 代码处理这些。

=====================

x_csr.dotx_csr.__mul__ 执行,当 other 稀疏时由 x_csr._mul_sparse_matrix(self, other) 执行。这使用 sparse.sputils.get_index_dtype 来确定返回值索引的 dtype。它在 Suitable index data type (int32 or int64).

之间选择

它还将所有输入转换为该数据类型

np.asarray(self.indptr, dtype=idx_dtype),

所以您尝试更改 x_csr.indptr dtype 不会更改计算方法。另请注意,在所有这些准备工作之后,实际的乘法运算是在编译的 C 代码中执行的 (csr_matmat_pass1csr_matmat_pass2)。