diff --git a/.github/workflows/test_and_build.yml b/.github/workflows/test_and_build.yml
index 7c7a7691b..190c1840e 100644
--- a/.github/workflows/test_and_build.yml
+++ b/.github/workflows/test_and_build.yml
@@ -173,12 +173,12 @@ jobs:
# Randomly choosing versions of dependencies based on Python version works surprisingly well...
if [[ ${{ startsWith(steps.pyver.outputs.selected, '3.9') }} == true ]]; then
npver=$(python -c 'import random ; print(random.choice(["=1.21", "=1.22", "=1.23", "=1.24", "=1.25", "=1.26", ""]))')
- spver=$(python -c 'import random ; print(random.choice(["=1.8", "=1.9", "=1.10", "=1.11", ""]))')
+ spver=$(python -c 'import random ; print(random.choice(["=1.9", "=1.10", "=1.11", ""]))')
pdver=$(python -c 'import random ; print(random.choice(["=1.2", "=1.3", "=1.4", "=1.5", "=2.0", "=2.1", ""]))')
akver=$(python -c 'import random ; print(random.choice(["=1.9", "=1.10", "=2.0", "=2.1", "=2.2", "=2.3", "=2.4", "=2.5", ""]))')
elif [[ ${{ startsWith(steps.pyver.outputs.selected, '3.10') }} == true ]]; then
npver=$(python -c 'import random ; print(random.choice(["=1.21", "=1.22", "=1.23", "=1.24", "=1.25", "=1.26", ""]))')
- spver=$(python -c 'import random ; print(random.choice(["=1.8", "=1.9", "=1.10", "=1.11", ""]))')
+ spver=$(python -c 'import random ; print(random.choice(["=1.9", "=1.10", "=1.11", ""]))')
pdver=$(python -c 'import random ; print(random.choice(["=1.3", "=1.4", "=1.5", "=2.0", "=2.1", ""]))')
akver=$(python -c 'import random ; print(random.choice(["=1.9", "=1.10", "=2.0", "=2.1", "=2.2", "=2.3", "=2.4", "=2.5", ""]))')
elif [[ ${{ startsWith(steps.pyver.outputs.selected, '3.11') }} == true ]]; then
@@ -196,9 +196,6 @@ jobs:
if [[ ${pdver} == "=2.1" && ${npver} == "=1.21" ]]; then
pdver="=2.0"
fi
- if [[ ${nxver} == "=3.2" && ${spver} == "=1.8" ]]; then
- spver="=1.9"
- fi
if [[ ${{ steps.sourcetype.outputs.selected }} == "source" || ${{ steps.sourcetype.outputs.selected }} == "upstream" ]]; then
# TODO: there are currently issues with some numpy versions when
# installing python-suitesparse-grphblas from source or upstream.
@@ -230,14 +227,11 @@ jobs:
fi
if [[ ${npver} == "=1.26" ]] ; then
numbaver=""
- if [[ ${spver} == "=1.8" || ${spver} == "=1.9" ]] ; then
+ if [[ ${spver} == "=1.9" ]] ; then
spver=$(python -c 'import random ; print(random.choice(["=1.10", "=1.11", ""]))')
fi
elif [[ ${npver} == "=1.25" ]] ; then
numbaver=""
- if [[ ${spver} == "=1.8" ]] ; then
- spver=$(python -c 'import random ; print(random.choice(["=1.9", "=1.10", "=1.11", ""]))')
- fi
elif [[ ${npver} == "=1.24" || ${{ startsWith(steps.pyver.outputs.selected, '3.11') }} == true ]] ; then
numbaver=$(python -c 'import random ; print(random.choice(["=0.57", "=0.58", ""]))')
elif [[ ${npver} == "=1.21" ]] ; then
diff --git a/docs/api_reference/io.rst b/docs/api_reference/io.rst
index cd6057a31..1cfc98516 100644
--- a/docs/api_reference/io.rst
+++ b/docs/api_reference/io.rst
@@ -10,15 +10,18 @@ These methods require `networkx `_ to be installed.
.. autofunction:: graphblas.io.to_networkx
-Numpy
+NumPy
~~~~~
-These methods require `scipy `_ to be installed, as some
-of the scipy.sparse machinery is used during the conversion process.
+These methods convert to and from dense arrays. For more, see :ref:`IO in the user guide `.
-.. autofunction:: graphblas.io.from_numpy
+.. automethod:: graphblas.core.matrix.Matrix.from_dense
-.. autofunction:: graphblas.io.to_numpy
+.. automethod:: graphblas.core.matrix.Matrix.to_dense
+
+.. automethod:: graphblas.core.vector.Vector.from_dense
+
+.. automethod:: graphblas.core.vector.Vector.to_dense
Scipy Sparse
~~~~~~~~~~~~
diff --git a/docs/user_guide/collections.rst b/docs/user_guide/collections.rst
index 2ce759bf4..de7469c6d 100644
--- a/docs/user_guide/collections.rst
+++ b/docs/user_guide/collections.rst
@@ -145,7 +145,7 @@ The shape and dtype remain unchanged, but the collection will be fully sparse (i
to_coo
~~~~~~
-To go from a collection back to the index and values, ``.to_coo()`` can be called. Numpy arrays
+To go from a collection back to the index and values, ``.to_coo()`` can be called. NumPy arrays
will be returned in a tuple.
.. code-block:: python
diff --git a/docs/user_guide/io.rst b/docs/user_guide/io.rst
index ecb4c0862..f27b40bd3 100644
--- a/docs/user_guide/io.rst
+++ b/docs/user_guide/io.rst
@@ -4,6 +4,8 @@ Input/Output
There are several ways to get data into and out of python-graphblas.
+.. _from-to-values:
+
From/To Values
--------------
diff --git a/graphblas/io/__init__.py b/graphblas/io/__init__.py
index b21b20963..a1b71db40 100644
--- a/graphblas/io/__init__.py
+++ b/graphblas/io/__init__.py
@@ -1,6 +1,5 @@
from ._awkward import from_awkward, to_awkward
from ._matrixmarket import mmread, mmwrite
from ._networkx import from_networkx, to_networkx
-from ._numpy import from_numpy, to_numpy # deprecated
from ._scipy import from_scipy_sparse, to_scipy_sparse
from ._sparse import from_pydata_sparse, to_pydata_sparse
diff --git a/graphblas/io/_numpy.py b/graphblas/io/_numpy.py
deleted file mode 100644
index 954d28df7..000000000
--- a/graphblas/io/_numpy.py
+++ /dev/null
@@ -1,104 +0,0 @@
-from warnings import warn
-
-from ..core.utils import output_type
-from ..core.vector import Vector
-from ..dtypes import lookup_dtype
-from ..exceptions import GraphblasException
-from ._scipy import from_scipy_sparse, to_scipy_sparse
-
-
-def from_numpy(m): # pragma: no cover (deprecated)
- """Create a sparse Vector or Matrix from a dense numpy array.
-
- .. deprecated:: 2023.2.0
- ``from_numpy`` will be removed in a future release.
- Use ``Vector.from_dense`` or ``Matrix.from_dense`` instead.
- Will be removed in version 2023.10.0 or later
-
- A value of 0 is considered as "missing".
-
- - m.ndim == 1 returns a ``Vector``
- - m.ndim == 2 returns a ``Matrix``
- - m.ndim > 2 raises an error
-
- dtype is inferred from m.dtype
-
- Parameters
- ----------
- m : np.ndarray
- Input array
-
- See Also
- --------
- Matrix.from_dense
- Vector.from_dense
- from_scipy_sparse
-
- Returns
- -------
- Vector or Matrix
- """
- warn(
- "`graphblas.io.from_numpy` is deprecated; "
- "use `Matrix.from_dense` and `Vector.from_dense` instead.",
- DeprecationWarning,
- stacklevel=2,
- )
- if m.ndim > 2:
- raise GraphblasException("m.ndim must be <= 2")
-
- try:
- from scipy.sparse import coo_array, csr_array
- except ImportError: # pragma: no cover (import)
- raise ImportError("scipy is required to import from numpy") from None
-
- if m.ndim == 1:
- A = csr_array(m)
- _, size = A.shape
- dtype = lookup_dtype(m.dtype)
- return Vector.from_coo(A.indices, A.data, size=size, dtype=dtype)
- A = coo_array(m)
- return from_scipy_sparse(A)
-
-
-def to_numpy(m): # pragma: no cover (deprecated)
- """Create a dense numpy array from a sparse Vector or Matrix.
-
- .. deprecated:: 2023.2.0
- ``to_numpy`` will be removed in a future release.
- Use ``Vector.to_dense`` or ``Matrix.to_dense`` instead.
- Will be removed in version 2023.10.0 or later
-
- Missing values will become 0 in the output.
-
- numpy dtype will match the GraphBLAS dtype
-
- Parameters
- ----------
- m : Vector or Matrix
- GraphBLAS Vector or Matrix
-
- See Also
- --------
- to_scipy_sparse
- Matrix.to_dense
- Vector.to_dense
-
- Returns
- -------
- np.ndarray
- """
- warn(
- "`graphblas.io.to_numpy` is deprecated; "
- "use `Matrix.to_dense` and `Vector.to_dense` instead.",
- DeprecationWarning,
- stacklevel=2,
- )
- try:
- import scipy # noqa: F401
- except ImportError: # pragma: no cover (import)
- raise ImportError("scipy is required to export to numpy") from None
- if output_type(m) is Vector:
- return to_scipy_sparse(m).toarray()[0]
- sparse = to_scipy_sparse(m, "coo")
- return sparse.toarray()
diff --git a/graphblas/tests/test_io.py b/graphblas/tests/test_io.py
index 6ad92a950..109c90a2c 100644
--- a/graphblas/tests/test_io.py
+++ b/graphblas/tests/test_io.py
@@ -38,17 +38,6 @@
suitesparse = gb.backend == "suitesparse"
-@pytest.mark.skipif("not ss")
-def test_deprecated():
- a = np.array([0.0, 2.0, 4.1])
- with pytest.warns(DeprecationWarning):
- v = gb.io.from_numpy(a)
- assert v.isequal(gb.Vector.from_coo([1, 2], [2.0, 4.1]), check_dtype=True)
- with pytest.warns(DeprecationWarning):
- a2 = gb.io.to_numpy(v)
- np.testing.assert_array_equal(a, a2)
-
-
@pytest.mark.skipif("not ss")
def test_vector_to_from_numpy():
a = np.array([0.0, 2.0, 4.1])