Scipy:稀疏矩阵条件去除列
Scipy: sparse matrix conditional removal of columns
我有一个大的 (79 000 x 480 000) 稀疏 csr 矩阵。我正在尝试删除每个值 < k.
的所有列(在一定范围内)
在常规的 numpy 矩阵中,这可以通过掩码简单地完成:
m = np.array([[0,2,1,1],
[0,4,2,0],
[0,3,4,0]])
mask = (arr < 2)
idx = mask.all(axis=0)
result = m[:, ~idx]
print result
>>> [[2 1]
[4 2]
[3 4]]
但是,一元按位求反运算符 ~ 和布尔掩码功能不适用于稀疏矩阵。最好的方法是什么:
- 获取所有值满足条件e < k的列的索引。
- 根据索引列表删除这些列。
一些注意事项:
- 这些列表示 ngram 文本特征:矩阵中没有每个元素都为零的列。
使用 csr 矩阵格式是否是一个合理的选择?
我是否转置并使用 .nonzero()?我有相当多的工作内存 (192GB),所以时间效率比内存效率更可取。
如果我这样做
M = sparse.csr_matrix(m)
M < 2
我收到效率警告; M的所有0值都满足条件,
In [1754]: print(M)
(0, 1) 2
(0, 2) 1
(0, 3) 1
(1, 1) 4
(1, 2) 2
(2, 1) 3
(2, 2) 4
In [1755]: print(M<2)
/usr/lib/python3/dist-packages/scipy/sparse/compressed.py:275: SparseEfficiencyWarning: Comparing a sparse matrix with a scalar greater than zero using < is inefficient, try using >= instead.
warn(bad_scalar_msg, SparseEfficiencyWarning)
(0, 0) True # not in M
(0, 2) True
(0, 3) True
(1, 0) True # not in M
(1, 3) True
(2, 0) True # not in M
(2, 3) True
In [1756]: print(M>=2) # all a subset of M
(0, 1) True
(1, 1) True
(1, 2) True
(2, 1) True
(2, 2) True
如果I=M>=2
;没有 all
方法,但是有 sum
.
In [1760]: I.sum(axis=0)
Out[1760]: matrix([[0, 3, 2, 0]], dtype=int32)
sum
实际上是使用矩阵乘法
执行的
In [1769]: np.ones((1,3),int)*I
Out[1769]: array([[0, 3, 2, 0]], dtype=int32)
使用 nonzero
查找非零列:
In [1778]: np.nonzero(I.sum(axis=0))
Out[1778]: (array([0, 0], dtype=int32), array([1, 2], dtype=int32))
In [1779]: M[:,np.nonzero(I.sum(axis=0))[1]]
Out[1779]:
<3x2 sparse matrix of type '<class 'numpy.int32'>'
with 6 stored elements in Compressed Sparse Row format>
In [1780]: M[:,np.nonzero(I.sum(axis=0))[1]].A
Out[1780]:
array([[2, 1],
[4, 2],
[3, 4]], dtype=int32)
总分:
比较时注意那些 0 值
在稀疏矩阵上执行逻辑时注意假值
稀疏矩阵针对数学进行了优化,尤其是矩阵乘法
稀疏索引不如数组索引强大;也没有那么快。
注意当操作产生密集矩阵时
我有一个大的 (79 000 x 480 000) 稀疏 csr 矩阵。我正在尝试删除每个值 < k.
的所有列(在一定范围内)在常规的 numpy 矩阵中,这可以通过掩码简单地完成:
m = np.array([[0,2,1,1],
[0,4,2,0],
[0,3,4,0]])
mask = (arr < 2)
idx = mask.all(axis=0)
result = m[:, ~idx]
print result
>>> [[2 1]
[4 2]
[3 4]]
但是,一元按位求反运算符 ~ 和布尔掩码功能不适用于稀疏矩阵。最好的方法是什么:
- 获取所有值满足条件e < k的列的索引。
- 根据索引列表删除这些列。
一些注意事项:
- 这些列表示 ngram 文本特征:矩阵中没有每个元素都为零的列。
使用 csr 矩阵格式是否是一个合理的选择? 我是否转置并使用 .nonzero()?我有相当多的工作内存 (192GB),所以时间效率比内存效率更可取。
如果我这样做
M = sparse.csr_matrix(m)
M < 2
我收到效率警告; M的所有0值都满足条件,
In [1754]: print(M)
(0, 1) 2
(0, 2) 1
(0, 3) 1
(1, 1) 4
(1, 2) 2
(2, 1) 3
(2, 2) 4
In [1755]: print(M<2)
/usr/lib/python3/dist-packages/scipy/sparse/compressed.py:275: SparseEfficiencyWarning: Comparing a sparse matrix with a scalar greater than zero using < is inefficient, try using >= instead.
warn(bad_scalar_msg, SparseEfficiencyWarning)
(0, 0) True # not in M
(0, 2) True
(0, 3) True
(1, 0) True # not in M
(1, 3) True
(2, 0) True # not in M
(2, 3) True
In [1756]: print(M>=2) # all a subset of M
(0, 1) True
(1, 1) True
(1, 2) True
(2, 1) True
(2, 2) True
如果I=M>=2
;没有 all
方法,但是有 sum
.
In [1760]: I.sum(axis=0)
Out[1760]: matrix([[0, 3, 2, 0]], dtype=int32)
sum
实际上是使用矩阵乘法
In [1769]: np.ones((1,3),int)*I
Out[1769]: array([[0, 3, 2, 0]], dtype=int32)
使用 nonzero
查找非零列:
In [1778]: np.nonzero(I.sum(axis=0))
Out[1778]: (array([0, 0], dtype=int32), array([1, 2], dtype=int32))
In [1779]: M[:,np.nonzero(I.sum(axis=0))[1]]
Out[1779]:
<3x2 sparse matrix of type '<class 'numpy.int32'>'
with 6 stored elements in Compressed Sparse Row format>
In [1780]: M[:,np.nonzero(I.sum(axis=0))[1]].A
Out[1780]:
array([[2, 1],
[4, 2],
[3, 4]], dtype=int32)
总分:
比较时注意那些 0 值
在稀疏矩阵上执行逻辑时注意假值
稀疏矩阵针对数学进行了优化,尤其是矩阵乘法
稀疏索引不如数组索引强大;也没有那么快。
注意当操作产生密集矩阵时