Python 提取一些列后,稀疏_csc矩阵的索引被反转

Python 提取一些列后,稀疏_csc矩阵的索引被反转,python,scipy,sparse-matrix,Python,Scipy,Sparse Matrix,我试图提取scipy稀疏列矩阵的列,但结果并没有像我预期的那样存储。我的意思是: 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)

我试图提取scipy稀疏列矩阵的列,但结果并没有像我预期的那样存储。我的意思是:

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.index
不是
[0,1,2,3,0,1,2,3]

由于这种行为不是我所期望的,因此
a[:,ind]
不是从csc矩阵中提取列的正确方法吗?

索引没有排序。您可以通过在a的行中反转强制循环(这不是那么直观),或者强制执行排序索引(您也可以就地执行,但我更喜欢强制转换)。我觉得有趣的是has_sorted_index属性并不总是返回布尔值,而是将其与整数表示混合在一起

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

csc
csr
索引不保证排序。我无法立即找到有效的文档,但是
有排序索引
,而
排序
方法表明了这一点

在您的案例中,顺序是如何进行索引的结果。我在前面的SO问题中发现,多列索引是通过矩阵乘法执行的:

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 [172]: b1 = a * I
In [173]: b1.indices
Out[173]: 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 [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 [172]: b1 = a * I
In [173]: b1.indices
Out[173]: array([3, 2, 1, 0, 3, 2, 1, 0], dtype=int32)
顺序是矩阵乘法的结果。事实上,
a*a.T
也做了同样的逆转。我们必须检查乘法代码才能知道确切的原因。显然,
csc
csr
计算代码不需要排序的
索引
,也不需要费心确保结果排序

进一步详情( CSR列索引不必排序。对于CSC行索引也是如此。当需要排序索引时(例如,将数据传递到其他库时),请使用.sorted_index()和.sort_index()方法