Manera eficiente de poner elementos a cero donde la máscara es verdadera en una matriz escasa escasa
Tengo dos scipy_sparse_csr_matrix 'a' y scipy_sparse_csr_matrix (boolean) 'mask', y quiero establecer los elementos de 'a' en cero donde el elemento de la máscara es True.
por ejemplo
>>>a
<3x3 sparse matrix of type '<type 'numpy.int32'>'
with 4 stored elements in Compressed Sparse Row format>
>>>a.todense()
matrix([[0, 0, 3],
[0, 1, 5],
[7, 0, 0]])
>>>mask
<3x3 sparse matrix of type '<type 'numpy.bool_'>'
with 4 stored elements in Compressed Sparse Row format>
>>>mask.todense()
matrix([[ True, False, True],
[False, False, True],
[False, True, False]], dtype=bool)
Entonces quiero obtener el siguiente resultado.
>>>result
<3x3 sparse matrix of type '<type 'numpy.int32'>'
with 2 stored elements in Compressed Sparse Row format>
>>>result.todense()
matrix([[0, 0, 0],
[0, 1, 0],
[7, 0, 0]])
Puedo hacerlo operando como
result = a - a.multiply(mask)
o
a -= a.multiply(mask) #I don't care either in-place or copy.
Pero creo que las operaciones anteriores son ineficientes. Dado que la forma real de 'a' y 'máscara' es 67,108,864 × 2,000,000, estas operaciones toman varios segundos en un servidor de alta especificación (CPU Xeon de 64 núcleos, memoria de 512GB). Por ejemplo, 'a' tiene aproximadamente 30,000,000 elementos que no son cero, y 'máscara' tiene aproximadamente 1,800,000 elementos que no son cero (Verdadero), luego la operación anterior toma aproximadamente 2 segundos.
¿Hay alguna forma más eficiente de hacer esto?
Las condiciones están abajo.
a.getnnz ()! = mask.getnnz ()a.shape = mask.shape¡Gracias!
Otra forma (probado)
a.data*=~np.array(mask[a.astype(np.bool)]).flatten();a.eliminate_zeros() #This takes twice the time longer than above method.