2017-08-08 76 views
2

我试图提取一个scipy稀疏列矩阵的列,但结果没有按照我的预期存储。这里就是我的意思是:提取一些列后sparse_csc矩阵的索引逆转

In [77]: a = scipy.sparse.csc_matrix(np.ones([4, 5])) 
In [78]: ind = np.array([True, True, False, False, False]) 
In [79]: b = a[:, ind] 

In [80]: b.indices 
Out[80]: array([3, 2, 1, 0, 3, 2, 1, 0], dtype=int32) 

In [81]: a.indices 
Out[81]: array([0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3], dtype=int32) 

为什么b.indices[0, 1, 2, 3, 0, 1, 2, 3]? 由于这种行为不是我期望的行为,因此a[:, ind]不是从csc矩阵中提取列的正确方法吗?

回答

1

该指数没有排序。你可以通过在行中反转来强制循环,这不是那么直观,或者强制排序索引(你也可以在原地进行,但我更喜欢投射)。我觉得有趣的是,has_sorted_indices属性并不总是返回一个布尔值,而是将其与整数表示混合。

a = scipy.sparse.csc_matrix(np.ones([4, 5])) 
ind = np.array([True, True, False, False, False]) 
b = a[::-1, ind] 
b2 = a[:, ind] 
b3 = b2.sorted_indices() 

b.indices 
>>array([0, 1, 2, 3, 0, 1, 2, 3], dtype=int32) 
b.has_sorted_indices 
>>1 
b2.indices 
>>array([3, 2, 1, 0, 3, 2, 1, 0], dtype=int32) 
b2.has_sorted_indices 
>>0 
b3.indices 
array([0, 1, 2, 3, 0, 1, 2, 3], dtype=int32) 
b3.has_sorted_indices 
>>True 
1

csccsr指数不保证进行排序。我无法脱手查找相关文档,但has_sort_indicessort方法表明。

在你的情况下,订单是如何完成索引的结果。我在以前的做题发现,多列索引与矩阵乘法进行:

In [165]: a = sparse.csc_matrix(np.ones([4,5])) 
In [166]: b = a[:,[0,1]] 
In [167]: b.indices 
Out[167]: array([3, 2, 1, 0, 3, 2, 1, 0], dtype=int32) 

该索引是相当于构建一个“选择”矩阵:

In [169]: I = sparse.csr_matrix(np.array([[1,0,0,0,0],[0,1,0,0,0]]).T) 
In [171]: I.A 
Out[171]: 
array([[1, 0], 
     [0, 1], 
     [0, 0], 
     [0, 0], 
     [0, 0]], dtype=int32) 

,做这个矩阵乘法:

In [172]: b1 = a * I 
In [173]: b1.indices 
Out[173]: array([3, 2, 1, 0, 3, 2, 1, 0], dtype=int32) 

该顺序是如何进行矩阵乘法的结果。实际上a * a.T做了相同的逆转。我们必须检查乘法代码以确切知道原因。显然csccsr计算代码不需要排序indices,并且不打扰以确保结果排序。

https://docs.scipy.org/doc/scipy-0.19.1/reference/sparse.html#further-details

而且Details¶ CSR列索引不一定排序。同样对于CSC行索引。当需要排序的索引时(例如,将数据传递到其他库时),使用.sorted_indices()和.sort_indices()方法。