Skip to content

Commit 86d711b

Browse files
committed
ENH: transition to SciPy sparse arrays from matrices
1 parent 352fc98 commit 86d711b

File tree

11 files changed

+95
-79
lines changed

11 files changed

+95
-79
lines changed

docs/construct.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -229,9 +229,9 @@ methods:
229229
* [`sparse.COO.todense`][]: Converts to a [`numpy.ndarray`][] unconditionally.
230230
* [`sparse.COO.maybe_densify`][]: Converts to a [`numpy.ndarray`][] based on
231231
certain constraints.
232-
* [`sparse.COO.to_scipy_sparse`][]: Converts to a [`scipy.sparse.coo_matrix`][] if
232+
* [`sparse.COO.to_scipy_sparse`][]: Converts to a [`scipy.sparse.coo_array`][] if
233233
the array is two dimensional.
234-
* [`sparse.COO.tocsr`][]: Converts to a [`scipy.sparse.csr_matrix`][] if
234+
* [`sparse.COO.tocsr`][]: Converts to a [`scipy.sparse.csr_array`][] if
235235
the array is two dimensional.
236-
* [`sparse.COO.tocsc`][]: Converts to a [`scipy.sparse.csc_matrix`][] if
236+
* [`sparse.COO.tocsc`][]: Converts to a [`scipy.sparse.csc_array`][] if
237237
the array is two dimensional.

sparse/numba_backend/_compressed/compressed.py

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -239,7 +239,7 @@ def dtype(self):
239239
See Also
240240
--------
241241
- [`numpy.ndarray.dtype`][] : Numpy equivalent property.
242-
- [`scipy.sparse.csr_matrix.dtype`][] : Scipy equivalent property.
242+
- [`scipy.sparse.csr_array.dtype`][] : Scipy equivalent property.
243243
"""
244244
return self.data.dtype
245245

@@ -258,7 +258,7 @@ def nnz(self):
258258
- [`sparse.COO.nnz`][] : Equivalent [`sparse.COO`][] array property.
259259
- [`sparse.DOK.nnz`][] : Equivalent [`sparse.DOK`][] array property.
260260
- [`numpy.count_nonzero`][] : A similar Numpy function.
261-
- [`scipy.sparse.coo_matrix.nnz`][] : The Scipy equivalent property.
261+
- [`scipy.sparse.coo_array.nnz`][] : The Scipy equivalent property.
262262
"""
263263
return self.data.shape[0]
264264

@@ -388,7 +388,7 @@ def _reduce_return(self, data, arr_attrs, result_fill_value):
388388
def change_compressed_axes(self, new_compressed_axes):
389389
"""
390390
Returns a new array with specified compressed axes. This operation is similar to converting
391-
a scipy.sparse.csc_matrix to a scipy.sparse.csr_matrix.
391+
a scipy.sparse.csc_array to a scipy.sparse.csr_array.
392392
393393
Returns
394394
-------
@@ -474,7 +474,7 @@ def todense(self):
474474
--------
475475
- [`sparse.DOK.todense`][] : Equivalent [`sparse.DOK`][] array method.
476476
- [`sparse.COO.todense`][] : Equivalent [`sparse.COO`][] array method.
477-
- [`scipy.sparse.coo_matrix.todense`][] : Equivalent Scipy method.
477+
- [`scipy.sparse.coo_array.todense`][] : Equivalent Scipy method.
478478
479479
"""
480480
if self.compressed_axes is None:
@@ -494,7 +494,7 @@ def todok(self):
494494

495495
def to_scipy_sparse(self, accept_fv=None):
496496
"""
497-
Converts this [`sparse.GCXS`][] object into a [`scipy.sparse.csr_matrix`][] or [`scipy.sparse.csc_matrix`][].
497+
Converts this [`sparse.GCXS`][] object into a [`scipy.sparse.csr_array`][] or [`scipy.sparse.csc_array`][].
498498
499499
Parameters
500500
----------
@@ -503,7 +503,7 @@ def to_scipy_sparse(self, accept_fv=None):
503503
504504
Returns
505505
-------
506-
scipy.sparse.csr_matrix or scipy.sparse.csc_matrix
506+
scipy.sparse.csr_array or scipy.sparse.csc_array
507507
The converted Scipy sparse matrix.
508508
509509
Raises
@@ -520,9 +520,9 @@ def to_scipy_sparse(self, accept_fv=None):
520520
raise ValueError("Can only convert a 2-dimensional array to a Scipy sparse matrix.")
521521

522522
if 0 in self.compressed_axes:
523-
return scipy.sparse.csr_matrix((self.data, self.indices, self.indptr), shape=self.shape)
523+
return scipy.sparse.csr_array((self.data, self.indices, self.indptr), shape=self.shape)
524524

525-
return scipy.sparse.csc_matrix((self.data, self.indices, self.indptr), shape=self.shape)
525+
return scipy.sparse.csc_array((self.data, self.indices, self.indptr), shape=self.shape)
526526

527527
def asformat(self, format, **kwargs):
528528
"""
@@ -751,8 +751,8 @@ def _2d_transpose(self):
751751
752752
See Also
753753
--------
754-
scipy.sparse.csr_matrix.transpose : Scipy equivalent function.
755-
scipy.sparse.csc_matrix.transpose : Scipy equivalent function.
754+
scipy.sparse.csr_array.transpose : Scipy equivalent function.
755+
scipy.sparse.csc_array.transpose : Scipy equivalent function.
756756
numpy.ndarray.transpose : Numpy equivalent function.
757757
"""
758758
if self.ndim != 2:
@@ -791,7 +791,7 @@ def dot(self, other):
791791
--------
792792
- [`sparse.dot`][] : Equivalent function for two arguments.
793793
- [`numpy.dot`][] : Numpy equivalent function.
794-
- [`scipy.sparse.coo_matrix.dot`][] : Scipy equivalent function.
794+
- [`scipy.sparse.coo_array.dot`][] : Scipy equivalent function.
795795
"""
796796
from .._common import dot
797797

sparse/numba_backend/_coo/core.py

Lines changed: 28 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -397,7 +397,7 @@ def todense(self):
397397
See Also
398398
--------
399399
- [`sparse.DOK.todense`][] : Equivalent `DOK` array method.
400-
- [`scipy.sparse.coo_matrix.todense`][] : Equivalent Scipy method.
400+
- [`scipy.sparse.coo_array.todense`][] : Equivalent Scipy method.
401401
402402
Examples
403403
--------
@@ -451,11 +451,14 @@ def from_scipy_sparse(cls, x, /, *, fill_value=None):
451451
x.eliminate_zeros()
452452
x.sum_duplicates()
453453

454-
coords = np.empty((2, x.nnz), dtype=x.row.dtype)
455-
coords[0, :] = x.row
456-
coords[1, :] = x.col
454+
def _coords(x):
455+
c = getattr(x, "coords", None)
456+
if c is None: # legacy support for SciPy sparse matrices
457+
c = (x.row, x.col)
458+
return c
459+
457460
return COO(
458-
coords,
461+
_coords(x),
459462
x.data,
460463
shape=x.shape,
461464
has_duplicates=not x.has_canonical_format,
@@ -562,7 +565,7 @@ def dtype(self):
562565
See Also
563566
--------
564567
- [`numpy.ndarray.dtype`][] : Numpy equivalent property.
565-
- [`scipy.sparse.coo_matrix.dtype`][] : Scipy equivalent property.
568+
- [`scipy.sparse.coo_array.dtype`][] : Scipy equivalent property.
566569
567570
Examples
568571
--------
@@ -590,7 +593,7 @@ def nnz(self):
590593
--------
591594
- [`sparse.DOK.nnz`][] : Equivalent [`sparse.DOK`][] array property.
592595
- [`numpy.count_nonzero`][] : A similar Numpy function.
593-
- [`scipy.sparse.coo_matrix.nnz`][] : The Scipy equivalent property.
596+
- [`scipy.sparse.coo_array.nnz`][] : The Scipy equivalent property.
594597
595598
Examples
596599
--------
@@ -945,7 +948,7 @@ def dot(self, other):
945948
--------
946949
- [`sparse.dot`][] : Equivalent function for two arguments.
947950
- [`numpy.dot`][] : Numpy equivalent function.
948-
- [`scipy.sparse.coo_matrix.dot`][] : Scipy equivalent function.
951+
- [`scipy.sparse.coo_array.dot`][] : Scipy equivalent function.
949952
950953
Examples
951954
--------
@@ -1160,7 +1163,7 @@ def squeeze(self, axis=None):
11601163

11611164
def to_scipy_sparse(self, /, *, accept_fv=None):
11621165
"""
1163-
Converts this [`sparse.COO`][] object into a [`scipy.sparse.coo_matrix`][].
1166+
Converts this [`sparse.COO`][] object into a [`scipy.sparse.coo_array`][].
11641167
11651168
Parameters
11661169
----------
@@ -1169,7 +1172,7 @@ def to_scipy_sparse(self, /, *, accept_fv=None):
11691172
11701173
Returns
11711174
-------
1172-
scipy.sparse.coo_matrix
1175+
scipy.sparse.coo_array
11731176
The converted Scipy sparse matrix.
11741177
11751178
Raises
@@ -1181,17 +1184,14 @@ def to_scipy_sparse(self, /, *, accept_fv=None):
11811184
11821185
See Also
11831186
--------
1184-
- [`sparse.COO.tocsr`][] : Convert to a [`scipy.sparse.csr_matrix`][].
1185-
- [`sparse.COO.tocsc`][] : Convert to a [`scipy.sparse.csc_matrix`][].
1187+
- [`sparse.COO.tocsr`][] : Convert to a [`scipy.sparse.csr_array`][].
1188+
- [`sparse.COO.tocsc`][] : Convert to a [`scipy.sparse.csc_array`][].
11861189
"""
11871190
import scipy.sparse
11881191

11891192
check_fill_value(self, accept_fv=accept_fv)
11901193

1191-
if self.ndim != 2:
1192-
raise ValueError("Can only convert a 2-dimensional array to a Scipy sparse matrix.")
1193-
1194-
result = scipy.sparse.coo_matrix((self.data, (self.coords[0], self.coords[1])), shape=self.shape)
1194+
result = scipy.sparse.coo_array((self.data, self.coords), shape=self.shape)
11951195
result.has_canonical_format = True
11961196
return result
11971197

@@ -1206,15 +1206,15 @@ def _tocsr(self):
12061206
indptr = np.zeros(self.shape[0] + 1, dtype=np.int64)
12071207
np.cumsum(np.bincount(row, minlength=self.shape[0]), out=indptr[1:])
12081208

1209-
return scipy.sparse.csr_matrix((self.data, col, indptr), shape=self.shape)
1209+
return scipy.sparse.csr_array((self.data, col, indptr), shape=self.shape)
12101210

12111211
def tocsr(self):
12121212
"""
1213-
Converts this array to a [`scipy.sparse.csr_matrix`][].
1213+
Converts this array to a [`scipy.sparse.csr_array`][].
12141214
12151215
Returns
12161216
-------
1217-
scipy.sparse.csr_matrix
1217+
scipy.sparse.csr_array
12181218
The result of the conversion.
12191219
12201220
Raises
@@ -1226,9 +1226,9 @@ def tocsr(self):
12261226
12271227
See Also
12281228
--------
1229-
- [`sparse.COO.tocsc`][] : Convert to a [`scipy.sparse.csc_matrix`][].
1230-
- [`sparse.COO.to_scipy_sparse`][] : Convert to a [`scipy.sparse.coo_matrix`][].
1231-
- [`scipy.sparse.coo_matrix.tocsr`][] : Equivalent Scipy function.
1229+
- [`sparse.COO.tocsc`][] : Convert to a [`scipy.sparse.csc_array`][].
1230+
- [`sparse.COO.to_scipy_sparse`][] : Convert to a [`scipy.sparse.coo_array`][].
1231+
- [`scipy.sparse.coo_array.tocsr`][] : Equivalent Scipy function.
12321232
"""
12331233
check_zero_fill_value(self)
12341234

@@ -1250,11 +1250,11 @@ def tocsr(self):
12501250

12511251
def tocsc(self):
12521252
"""
1253-
Converts this array to a [`scipy.sparse.csc_matrix`][].
1253+
Converts this array to a [`scipy.sparse.csc_array`][].
12541254
12551255
Returns
12561256
-------
1257-
scipy.sparse.csc_matrix
1257+
scipy.sparse.csc_array
12581258
The result of the conversion.
12591259
12601260
Raises
@@ -1266,9 +1266,9 @@ def tocsc(self):
12661266
12671267
See Also
12681268
--------
1269-
- [`sparse.COO.tocsr`][] : Convert to a [`scipy.sparse.csr_matrix`][].
1270-
- [`sparse.COO.to_scipy_sparse`][] : Convert to a [`scipy.sparse.coo_matrix`][].
1271-
- [`scipy.sparse.coo_matrix.tocsc`][] : Equivalent Scipy function.
1269+
- [`sparse.COO.tocsr`][] : Convert to a [`scipy.sparse.csr_array`][].
1270+
- [`sparse.COO.to_scipy_sparse`][] : Convert to a [`scipy.sparse.coo_array`][].
1271+
- [`scipy.sparse.coo_array.tocsc`][] : Equivalent Scipy function.
12721272
"""
12731273
check_zero_fill_value(self)
12741274

@@ -1320,7 +1320,7 @@ def _sum_duplicates(self):
13201320
13211321
See Also
13221322
--------
1323-
scipy.sparse.coo_matrix.sum_duplicates : Equivalent Scipy function.
1323+
scipy.sparse.coo_array.sum_duplicates : Equivalent Scipy function.
13241324
13251325
Examples
13261326
--------

sparse/numba_backend/_dok.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -258,7 +258,7 @@ def nnz(self):
258258
--------
259259
- [`sparse.COO.nnz`][] : Equivalent [`sparse.COO`][] array property.
260260
- [`numpy.count_nonzero`][] : A similar Numpy function.
261-
- [`scipy.sparse.coo_matrix.nnz`][] : The Scipy equivalent property.
261+
- [`scipy.sparse.coo_array.nnz`][] : The Scipy equivalent property.
262262
263263
Examples
264264
--------
@@ -450,7 +450,7 @@ def todense(self):
450450
See Also
451451
--------
452452
- [`sparse.COO.todense`][] : Equivalent `COO` array method.
453-
- [`scipy.sparse.coo_matrix.todense`][] : Equivalent Scipy method.
453+
- [`scipy.sparse.coo_array.todense`][] : Equivalent Scipy method.
454454
455455
Examples
456456
--------

sparse/numba_backend/_sparse_array.py

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ def nnz(self):
7474
--------
7575
- [`sparse.DOK.nnz`][] : Equivalent [`sparse.DOK`][] array property.
7676
- [`numpy.count_nonzero`][] : A similar Numpy function.
77-
- [`scipy.sparse.coo_matrix.nnz`][] : The Scipy equivalent property.
77+
- [`scipy.sparse.coo_array.nnz`][] : The Scipy equivalent property.
7878
7979
Examples
8080
--------
@@ -254,7 +254,7 @@ def todense(self):
254254
--------
255255
- [`sparse.DOK.todense`][] : Equivalent `DOK` array method.
256256
- [`sparse.COO.todense`][] : Equivalent `COO` array method.
257-
- [`scipy.sparse.coo_matrix.todense`][] : Equivalent Scipy method.
257+
- [`scipy.sparse.coo_array.todense`][] : Equivalent Scipy method.
258258
259259
Examples
260260
--------
@@ -453,7 +453,7 @@ def sum(self, axis=None, keepdims=False, dtype=None, out=None):
453453
See Also
454454
--------
455455
- [`numpy.sum`][] : Equivalent numpy function.
456-
- [`scipy.sparse.coo_matrix.sum`][] : Equivalent Scipy function.
456+
- [`scipy.sparse.coo_array.sum`][] : Equivalent Scipy function.
457457
"""
458458
return np.add.reduce(self, out=out, axis=axis, keepdims=keepdims, dtype=dtype)
459459

@@ -478,7 +478,7 @@ def max(self, axis=None, keepdims=False, out=None):
478478
See Also
479479
--------
480480
- [`numpy.max`][] : Equivalent numpy function.
481-
- [`scipy.sparse.coo_matrix.max`][] : Equivalent Scipy function.
481+
- [`scipy.sparse.coo_array.max`][] : Equivalent Scipy function.
482482
"""
483483
return np.maximum.reduce(self, out=out, axis=axis, keepdims=keepdims)
484484

@@ -549,7 +549,7 @@ def min(self, axis=None, keepdims=False, out=None):
549549
See Also
550550
--------
551551
- [`numpy.min`][] : Equivalent numpy function.
552-
- [`scipy.sparse.coo_matrix.min`][] : Equivalent Scipy function.
552+
- [`scipy.sparse.coo_array.min`][] : Equivalent Scipy function.
553553
"""
554554
return np.minimum.reduce(self, out=out, axis=axis, keepdims=keepdims)
555555

@@ -619,7 +619,7 @@ def astype(self, dtype, casting="unsafe", copy=True):
619619
620620
See Also
621621
--------
622-
- [`scipy.sparse.coo_matrix.astype`][] :
622+
- [`scipy.sparse.coo_array.astype`][] :
623623
SciPy sparse equivalent function
624624
- [`numpy.ndarray.astype`][] :
625625
NumPy equivalent ufunc.
@@ -653,7 +653,7 @@ def mean(self, axis=None, keepdims=False, dtype=None, out=None):
653653
See Also
654654
--------
655655
- [`numpy.ndarray.mean`][] : Equivalent numpy method.
656-
- [`scipy.sparse.coo_matrix.mean`][] : Equivalent Scipy method.
656+
- [`scipy.sparse.coo_array.mean`][] : Equivalent Scipy method.
657657
658658
Notes
659659
-----

sparse/numba_backend/tests/test_array_function.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -110,8 +110,8 @@ class TestAsarray:
110110
"input",
111111
[
112112
np_eye,
113-
scipy.sparse.csr_matrix(np_eye),
114-
scipy.sparse.csc_matrix(np_eye),
113+
scipy.sparse.csr_array(np_eye),
114+
scipy.sparse.csc_array(np_eye),
115115
4,
116116
np.array(5),
117117
np.arange(12).reshape((2, 3, 2)),

sparse/numba_backend/tests/test_compressed_2d.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ def test_from_sparse(cls, source_type):
7474
@pytest.mark.parametrize("scipy_type", ["coo", "csr", "csc", "lil"])
7575
@pytest.mark.parametrize("CLS", [CSR, CSC, GCXS])
7676
def test_from_scipy_sparse(scipy_type, CLS, dtype):
77-
orig = scipy.sparse.random(20, 30, density=0.2, format=scipy_type, dtype=dtype)
77+
orig = scipy.sparse.random_array((20, 30), density=0.2, format=scipy_type, dtype=dtype)
7878
ref = COO.from_scipy_sparse(orig)
7979
result = CLS.from_scipy_sparse(orig)
8080

sparse/numba_backend/tests/test_conversion.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ def test_non_canonical_conversion():
5353
indices = np.array((1, 0, 0, 1, 1), dtype=int)
5454
indptr = np.array((0, 2, 5), dtype=int)
5555

56-
x = sps.csr_matrix((data, indices, indptr), shape=(2, 2))
56+
x = sps.csr_array((data, indices, indptr), shape=(2, 2))
5757
ref = np.array(((1.0, 2.0), (3.0, 4.0)))
5858

5959
gcxs_check = sparse.GCXS(x)

0 commit comments

Comments
 (0)