Эффективно добавить столбец разреженной (csc) атрикс в плотный массив с правильной формой - PullRequest
0 голосов
/ 29 ноября 2018

К моему удивлению, происходит следующее:

In [1]: import numpy as np                                                                           

In [2]: from scipy import sparse                                                                     

In [3]: A = sparse.rand(10, 4, format='csc')                                                                       

In [4]: b = np.zeros(10)                                                                             

In [5]: b += A[:, 0]                                                                                                                                                               
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-7-8704096141d1> in <module>
----> 1 b += A[:, 0]

~/anaconda3/lib/python3.6/site-packages/scipy/sparse/base.py in __radd__(self, other)
    420 
    421     def __radd__(self,other):  # other + self
--> 422         return self.__add__(other)
    423 
    424     def __sub__(self, other):  # self - other

~/anaconda3/lib/python3.6/site-packages/scipy/sparse/base.py in __add__(self, other)
    414             return self._add_sparse(other)
    415         elif isdense(other):
--> 416             other = broadcast_to(other, self.shape)
    417             return self._add_dense(other)
    418         else:

~/anaconda3/lib/python3.6/site-packages/numpy/lib/stride_tricks.py in broadcast_to(array, shape, subok)
    171            [1, 2, 3]])
    172     """
--> 173     return _broadcast_to(array, shape, subok=subok, readonly=True)
    174 
    175 

~/anaconda3/lib/python3.6/site-packages/numpy/lib/stride_tricks.py in _broadcast_to(array, shape, subok, readonly)
    126     broadcast = np.nditer(
    127         (array,), flags=['multi_index', 'refs_ok', 'zerosize_ok'] + extras,
--> 128         op_flags=[op_flag], itershape=shape, order='C').itviews[0]
    129     result = _maybe_view_as_subclass(array, broadcast)
    130     if needs_writeable and not result.flags.writeable:

ValueError: operands could not be broadcast together with remapped shapes [original->remapped]: (10,) and requested shape (10,1)

Очевидным, но дорогостоящим решением было бы вызвать .toarray() на A[:, 0] перед добавлением его в b.Можно ли этого эффективно избежать с помощью встроенных функций scipy / numpy?

1 Ответ

0 голосов
/ 29 ноября 2018

Вы можете напрямую работать с форматом csc:

if not A.has_canonical_format:    # make sure indices are unique
    A.sum_duplicates()
l, r = A.indptr[idx:idx+2]        # find the relevant column
b[A.indices[l:r]] += A.data[l:r]  # add nonzero values at their offsets
...