保留大型矩阵产品的特定元素

eig*_*ein 2 numpy scipy sparse-matrix

我需要计算以下矩阵表达式:XT - Y并保持元素仅对应于矩阵的非零元素Y.例如,如果:

In [63]: X.dot(T.T) - Y
Out[63]: array([[ -6,  -2], [ -9, -12]])
In [64]: Y
Out[64]: array([[5, 0], [7, 8]])
Run Code Online (Sandbox Code Playgroud)

然后结果应该是[[-6, 0], [-9, -12]].

X并且T都是矢量.问题是,无论X.dot(T.T)Y具有大尺寸(比方说350 x 23 000 000),所以Y被存储为一个scipy.sparse.csc_matrix有大约2亿的值.我没有足够的内存来存储中间XT结果.

当然,可以迭代所有非零元素Y并手动计算每个元素,XT然后手动构造结果csc_matrix.结果将具有相同indicesindptr属性的Y,这让我觉得,应该有一个更短或更快的方式.

War*_*ser 5

这是你可以做到的一种方式.

首先,一些样本数据:

In [75]: X.T
Out[75]: array([[1, 2, 3]])

In [76]: T.T
Out[76]: array([[2, 3, 5, 7]])

In [77]: Y
Out[77]: 
<3x4 sparse matrix of type '<type 'numpy.int64'>'
    with 5 stored elements in Compressed Sparse Column format>

In [78]: Y.A
Out[78]: 
array([[0, 0, 4, 5],
       [6, 0, 0, 7],
       [0, 8, 0, 0]])
Run Code Online (Sandbox Code Playgroud)

转换Y为COO格式(因此非零数据的行和列索引随时可用):

In [79]: C = Y.tocoo()
Run Code Online (Sandbox Code Playgroud)

计算等效X.dot(T.T) - Y值,但仅适用于Y非零值:

In [80]: data = X[C.row,0]*T[C.col,0] - C.data

In [81]: data
Out[81]: array([-2,  1,  1,  2,  7])
Run Code Online (Sandbox Code Playgroud)

与完整计算相比:

In [82]: X.dot(T.T) - Y
Out[82]: 
matrix([[ 2,  3,  1,  2],
        [-2,  6, 10,  7],
        [ 6,  1, 15, 21]])
Run Code Online (Sandbox Code Playgroud)

如果您需要CSC矩阵中的结果,例如Y:

In [84]: D = csc_matrix((data, (C.row, C.col)), shape=C.shape)

In [85]: D
Out[85]: 
<3x4 sparse matrix of type '<type 'numpy.int64'>'
    with 5 stored elements in Compressed Sparse Column format>

In [86]: D.A
Out[86]: 
array([[ 0,  0,  1,  2],
       [-2,  0,  0,  7],
       [ 0,  1,  0,  0]])
Run Code Online (Sandbox Code Playgroud)