我正在尝试提取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.indices
不是[0, 1, 2, 3, 0, 1, 2, 3]
?
既然这种行为不是我所期望的,那么a[:, ind]
不是从csc矩阵中提取列的正确方法吗?
答案 0 :(得分: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 :(得分:1)
csc
和csr
索引不保证排序。我无法找到效果的文档,但has_sort_indices
和sort
方法表明了这一点。
在您的情况下,订单是索引编制方式的结果。我在之前的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 [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
做了同样的逆转。我们必须检查乘法代码以确切知道原因。显然,csc
和csr
计算代码不需要排序indices
,也不会确保对结果进行排序。
https://docs.scipy.org/doc/scipy-0.19.1/reference/sparse.html#further-details
更多细节¶ CSR列索引不一定要排序。同样对于CSC行索引。当需要排序索引时(例如,将数据传递给其他库时),请使用.sorted_indices()和.sort_indices()方法。