从scipy稀疏矩阵中过滤值

15

我正在尝试从一个巨大的CSR矩阵(SciPy)中过滤小于10的值。 由于所有的值都是整数,除以10再乘以10可以实现,但我想知道是否有更好的方法来筛选元素。

编辑: 下面的答案可行。请检查您是否安装了最新版本的SciPy。


这是怎么回事?11 / 10 * 10 = 10,而不是11。 - wflynny
对于我的特定应用程序来说,这已经足够好了,但正如我所说,应该有更好的方法(即更快,更准确)来完成它。 - Omer
2个回答

11

你也可以选择更不熟练但可能更慢的方法:

m = m.multiply(m >= 10)

为了理解正在发生的事情:

>>> m = scipy.sparse.csr_matrix((1000, 1000), dtype=np.int)
>>> m[np.random.randint(0, 1000, 20),
      np.random.randint(0, 1000, 20)] = np.random.randint(0, 100, 20)
>>> m.data
array([92, 46, 99, 24, 75, 16, 49, 60, 87, 64, 91, 37, 30, 32, 25, 40, 99,
        9,  3, 84])
>>> m >= 10
<1000x1000 sparse matrix of type '<type 'numpy.bool_'>'
    with 18 stored elements in Compressed Sparse Row format>
>>> m = m.multiply(m >= 10)
>>> m
<1000x1000 sparse matrix of type '<type 'numpy.int32'>'
    with 18 stored elements in Compressed Sparse Row format>
>>> m.data
array([92, 46, 99, 24, 75, 16, 49, 60, 87, 64, 91, 37, 30, 32, 25, 40, 99,
       84])

我不确定称直接操作压缩表示为“hacky”是否公平 - 毕竟该表示已经记录了。 - Gareth Rees
请别误会,我认为你的回答完全有效。你现在的单个赞就是我的。;) 我有关于稀疏矩阵的答案,其中涉及到所有三个内部数组的可怕复杂性。这样的hacky操作是合理的,因为scipy.sparse仍在不断发展中,每次发布都会有巨大的功能飞跃。但是,虽然我们还没有达到那个目标,最终的目标应该是能够像处理任何数组一样进行m[m < 10] = 0,然后完成它。我认为我的答案更接近这个理想。 - Jaime
谢谢Jaime!将(m> = 10)解释为矩阵是一个新功能吗?在我的SciPy版本中似乎不起作用。 - Omer
1
@Omer,我不得不将Scipy从0.10升级到0.13才能使其正常工作。 - cjauvin
1
什么是不太正规但更快的版本? - Moj
@GarethRees 曾经有一个已被删除的答案,大致做了以下操作:m.data[m.data < 10] = 0; m.eliminate_zeros() - Jaime

2
我认为版本问题与比较运算符的实现有关。 m >= 0 使用了m.__gt__。(我没有早期版本的scipy来测试,但我相信有一个或多个SO线程讨论了这个问题)。
在早期版本中可能有效的一些方法是:
m.data *= m.data>=10
m.eliminate_zeros()

换句话说,使用标准的numpy操作将选定的值设置为0。测试可能会更加复杂。然后使用标准的sparse函数进行清理。当你说“过滤”时,你想做的本质上就是这样:将某些值设为零并从稀疏矩阵中删除它们。

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