sparse_csc 矩阵的索引在提取某些列后反转
indices of sparse_csc matrix are reversed after extracting some columns
我正在尝试提取 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 矩阵中提取列的正确方法吗?
索引未排序。您可以通过在 a 的行中反转来强制循环,这不是那么直观,或者强制执行排序索引(您也可以就地执行,但我更喜欢转换)。我觉得有趣的是 has_sorted_indices 属性并不总是 return 布尔值,而是将它与整数表示混合。
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
索引不保证排序。我无法立即找到相关文档,但 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)
这个索引等价于构造一个'selection'矩阵:
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
Further Details¶
CSR column indices are not necessarily sorted. Likewise for CSC row indices. Use the .sorted_indices() and .sort_indices() methods when sorted indices are required (e.g. when passing data to other libraries).
我正在尝试提取 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 矩阵中提取列的正确方法吗?
索引未排序。您可以通过在 a 的行中反转来强制循环,这不是那么直观,或者强制执行排序索引(您也可以就地执行,但我更喜欢转换)。我觉得有趣的是 has_sorted_indices 属性并不总是 return 布尔值,而是将它与整数表示混合。
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
索引不保证排序。我无法立即找到相关文档,但 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)
这个索引等价于构造一个'selection'矩阵:
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
Further Details¶ CSR column indices are not necessarily sorted. Likewise for CSC row indices. Use the .sorted_indices() and .sort_indices() methods when sorted indices are required (e.g. when passing data to other libraries).