用1填充Scipy稀疏矩阵

3

我有一个scipy稀疏矩阵,想将其中的值替换为1:

from scipy import sparse
import numpy as np

data = np.array([[1, 2, 3, 0, 5], [6, 0, 0, 9, 10], [0, 0, 0, 0, 15]])

print sparse.coo_matrix(data)

我看到numpy有一个ones_like()函数,但是它并没有解决我的问题。
输出应该像这样:
(0, 0)        1
(0, 1)        1
(0, 2)        1
(0, 4)        1
(1, 0)        1
(1, 3)        1
(1, 4)        1
(2, 4)        1
2个回答

4
最简单的方法是直接操作稀疏矩阵表示。如何操作取决于您选择的表示方式;对于 COO 格式,操作方式如下:
data.data[:] = 1

请注意,COO格式有一个奇怪的特点,它允许重复的条目。如果COO矩阵在位置(1,1)处有两个条目,上述代码将把这两个条目都设置为1,导致将矩阵转换为另一种格式后只剩下一个条目2。如果您想要一个单一的条目1,那么您可以先对重复项进行规范化。
data.sum_duplicates()
data.data[:] = 1

如果原始的 coo 是从一个密集的数组构建的,那么这种 重复输入 功能(我恰好喜欢它)就不是一个问题。只有当你从“原始”数据、行、列数组构建 coo 时才会出现这个问题。 - hpaulj

0
如果您只需要在矩阵的特定列中放置1,您可以使用scipy.sparse getnnz函数来执行此操作。通过在axis=1上使用该函数选择列,您可以获得一个新列,其中仅在相应位置上有1。
data[:,col] = csc_matrix(data[:,col].getnnz(axis=1)).T

当然,将csc_matrix替换为您正在使用的稀疏类型,但请注意,在csc_matrix中切片列更有效率,因此在执行此操作之前,请考虑将矩阵转换为csc_matrix(如果您有一个csr_matrix,则可以修改此算法以在行中循环)。


你能否评论一下与已接受答案相比的速度差异?我担心for循环会使其效率低下。 - slaw
事情是,我试着用被接受的答案,但我无法修改矩阵中某一列的数据属性。我试着用data [:,0] .data = np.ones(..),但这行不通,似乎会实例化另一个矩阵。我将研究效率并告诉你。 - Federico Caccia
1
这种方法比被接受的答案更有效率。另外一种方式只是很好地修改了某些列的值(所以我更新了答案)。 - Federico Caccia

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接