【发布时间】:2018-11-05 14:27:01
【问题描述】:
如何对 scipy 稀疏矩阵的一些行进行采样,并从这些采样行中形成一个新的 scipy 稀疏矩阵?
例如。如果我有一个 10 行的 scipy 稀疏矩阵 A,并且我想从 A 中创建一个具有第 1、3、4 行的新 scipy 稀疏矩阵 B,该怎么做?
【问题讨论】:
标签: python python-3.x numpy scipy
如何对 scipy 稀疏矩阵的一些行进行采样,并从这些采样行中形成一个新的 scipy 稀疏矩阵?
例如。如果我有一个 10 行的 scipy 稀疏矩阵 A,并且我想从 A 中创建一个具有第 1、3、4 行的新 scipy 稀疏矩阵 B,该怎么做?
【问题讨论】:
标签: python python-3.x numpy scipy
用适当的指标矩阵左乘。指标矩阵可以使用scipy.sparse.block_diag构建,也可以直接使用csr格式构建,如下图。
>>> import numpy as np
>>> from scipy import sparse
>>>
# create example
>>> m, n = 10, 8
>>> subset = [1,3,4]
>>> A = sparse.csr_matrix(np.random.randint(-10, 5, (m, n)).clip(0, None))
>>> A.A
array([[3, 2, 4, 0, 0, 0, 2, 0],
[0, 0, 2, 0, 0, 0, 0, 0],
[4, 0, 0, 0, 0, 2, 0, 0],
[0, 0, 0, 0, 0, 0, 4, 0],
[3, 0, 0, 0, 1, 4, 0, 0],
[0, 0, 0, 0, 0, 0, 2, 0],
[0, 0, 0, 4, 0, 4, 4, 0],
[0, 2, 0, 0, 0, 3, 0, 0],
[4, 0, 3, 3, 0, 0, 0, 2],
[4, 0, 0, 0, 0, 2, 0, 1]], dtype=int64)
>>>
# build indicator matrix
# either using block_diag ...
>>> split_points = np.arange(len(subset)+1).repeat(np.diff(np.concatenate([[0], subset, [m-1]])))
>>> indicator = sparse.block_diag(np.split(np.ones(len(subset), int), split_points)).T
>>> indicator.A
array([[0, 1, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 1, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 1, 0, 0, 0, 0, 0]], dtype=int64)
>>>
# ... or manually---this also works for non sorted non unique subset,
# and is therefore to be preferred over block_diag
>>> indicator = sparse.csr_matrix((np.ones(len(subset), int), subset, np.arange(len(subset)+1)), (len(subset), m))
>>> indicator.A
array([[0, 1, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 1, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 1, 0, 0, 0, 0, 0]])
>>>
# apply
>>> result = indicator@A
>>> result.A
array([[0, 0, 2, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 4, 0],
[3, 0, 0, 0, 1, 4, 0, 0]], dtype=int64)
【讨论】:
indicator = sparse.csr_matrix((your_weights, subset, np.arange(len(subset)+1)), (len(subset), m))。在第二种情况下,使用 `indicator = sparse.csr_matrix((np.ones(np.sum(your_repeats), int), np.repeat(subset, your_repeats), np.arange(np.sum(your_repeats)+1)) , (np.sum(your_repeats), m))
csr 设置可能仍然比替代设置更快(例如转换为lil)。