70379

How to get views on sparse matrices?

Question:

When slicing a numpy array we obtain a view on the corresponding data. However that doesn't seem to be the case with sparse matrices from <a href="https://docs.scipy.org/doc/scipy/reference/sparse.html" rel="nofollow">scipy.sparse</a>. Although <a href="https://docs.scipy.org/doc/scipy/reference/sparse.html#usage-information" rel="nofollow">the docs</a> briefly mention slicing for the lil_matrix class it's not clear how (or if) one can obtain views on the data.

At least by using the following sample script I wasn't successful in obtaining views of sparse matrices:

import numpy as np from scipy.sparse import lil_matrix def test(matrix): print('\n=== Testing {} ==='.format(type(matrix))) a = matrix[:, 0] b = matrix[0, :] a[0] = 100 M[0, 1] = 200 M[1, 0] = 200 print('a = '); print(a) print('b = '); print(b) M = np.arange(4).reshape(2, 2) + 1 S = lil_matrix(M) test(M) test(S)

Which outputs:

=== Testing <class 'numpy.ndarray'> === a = [100 200] b = [100 200] === Testing <class 'scipy.sparse.lil.lil_matrix'> === a = (0, 0) 100 (1, 0) 3 b = (0, 0) 1 (0, 1) 2 <hr />

<strong>Tested on</strong> Python 3.6.6, numpy==1.14.5, scipy==1.1.0.

Answer1:

I'll eat my words - partially. There is a lilmatrix getrowview method (but not a getcolview).

A lil matrix has 2 object dtype array attributes, data and rows. Both contain lists, one for each row.

def getrow(self, i): """Returns a copy of the 'i'th row. """ i = self._check_row_bounds(i) new = lil_matrix((1, self.shape[1]), dtype=self.dtype) new.rows[0] = self.rows[i][:] new.data[0] = self.data[i][:] return new def getrowview(self, i): """Returns a view of the 'i'th row (without copying). """ new = lil_matrix((1, self.shape[1]), dtype=self.dtype) new.rows[0] = self.rows[i] new.data[0] = self.data[i] return new

A little testing shows that modifying elements of the row view does affect the parent, and v.v.

This view works because an object array contains pointers. As with pointers in a list, they can be shared. And if done right, such a list can be modified in-place.

I found this by doing a page search for view on the lil_matrix documentation. I don't find anything similar for the other formats.

There are numerical functions on the csr format that work directly with the .data attribute. This is possible if you aren't changing sparsity, and only want to modify the nonzero values. And it is possible to modify that attribute in place. In limited cases it might be possible to construct a new sparse matrix that shares slices of the data attribute of another, but it would not be anything as general as ndarray slicing.

<hr />In [88]: M = sparse.lil_matrix((4,10),dtype=int) In [89]: M[0,1::2] = 1 In [90]: M[1,::2] = 2 In [91]: M1 = M.getrowview(0) In [92]: M1[0,::2] = 3 In [94]: M.A Out[94]: array([[3, 1, 3, 1, 3, 1, 3, 1, 3, 1], [2, 0, 2, 0, 2, 0, 2, 0, 2, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]]) In [95]: M[0,1::2] = 4 In [97]: M1.A Out[97]: array([[3, 4, 3, 4, 3, 4, 3, 4, 3, 4]])

Following this model I could make an 'advanced-indexview, something thatndarray` doesn't do:

In [98]: M2 = sparse.lil_matrix((2,10), dtype=int) In [99]: M2.rows[:] = M.rows[[0,3]] In [100]: M2.data[:] = M.data[[0,3]] In [101]: M2.A Out[101]: array([[3, 4, 3, 4, 3, 4, 3, 4, 3, 4], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]]) In [102]: M2[:,::2] *= 10 In [103]: M2.A Out[103]: array([[30, 4, 30, 4, 30, 4, 30, 4, 30, 4], [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]]) In [104]: M1.A Out[104]: array([[30, 4, 30, 4, 30, 4, 30, 4, 30, 4]])

Recommend

  • how to read all the subdirectories in a given destination which contain Master File in it
  • Using Global vars in GAS, is it advisable? are there any downsides?
  • Simplest way to save array into raster file in Python
  • Inserting null columns into a scipy sparse matrix in a specific order
  • Mean value of each channel of several images
  • Repeat each values of an array different times
  • Why can't I create a numpy array like this: array([1, 2], 3)
  • Display a numeric keypad on activity without an input area
  • Refresh other frame, from another frame. Jquery
  • Full 8 bit adder, illogical output
  • Calling java project from Mathematica
  • PHP file_exists() anomaly
  • Insertion large number of Entities into SQL Server 2012 [duplicate]
  • Add reference to ASP.NET 5 Class Library from Framework 4.5 Class Library Project
  • import scipy.sparse failed
  • C#: Import/Export Settings into/from a File
  • During installation of Django, why do I keep getting ImportError: No module named django?
  • where do I find the xml.dom python package for the python-2.6.0-8.9.28 and I have a suse/x86_64 vers
  • Python pickle not one-to-one: different pickles give same object
  • Why use database factory in asp.net mvc?
  • Ionic 2 storage is not cleaning up on uninstall - Only for signed APK
  • preg_replace Double Spaces to tab (\\t) at the beginning of a line
  • ImageMagick, replace semi-transparent white with opaque white
  • sending/ receiving email in Java
  • Font Awesome Showing Box instead of Icons
  • Properly structure and highlight a GtkPopoverMenu using PyGObject
  • VB.net deserialize, JSON Conversion from type 'Dictionary(Of String,Object)' to type '
  • How can I get HTML syntax highlighting in my editor for CakePHP?
  • How do I configure my settings file to work with unit tests?
  • How to get Windows thread pool to call class member function?
  • IndexOutOfRangeException on multidimensional array despite using GetLength check
  • Is it possible to post an object from jquery to bottle.py?
  • costura.fody for a dll that references another dll
  • Binding checkboxes to object values in AngularJs
  • Observable and ngFor in Angular 2
  • How to Embed XSL into XML
  • UserPrincipal.Current returns apppool on IIS
  • Conditional In-Line CSS for IE and Others?
  • Python/Django TangoWithDjango Models and Databases
  • java string with new operator and a literal