Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rm to_numpy_recarray #5737

Merged
merged 3 commits into from Jun 15, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 0 additions & 1 deletion doc/developer/deprecations.rst
Expand Up @@ -106,7 +106,6 @@ Version 3.0
reflect that the function returns a ``numpy.ndarray`` instance.
* In ``generators/small.py`` remove ``make_small_graph`` and
``make_small_undirected_graph``.
* In ``convert_matrix.py`` remove ``to_numpy_recarray``.
* In ``classes/function.py`` remove ``info``.
* In ``algorithms/community/modularity_max.py``, remove the deprecated
``n_communities`` parameter from the ``greedy_modularity_communities``
Expand Down
3 changes: 0 additions & 3 deletions networkx/conftest.py
Expand Up @@ -231,9 +231,6 @@ def set_warnings():
warnings.filterwarnings(
"ignore", category=DeprecationWarning, message=r"\n\nmake_small_.*"
)
warnings.filterwarnings(
"ignore", category=DeprecationWarning, message="to_numpy_recarray"
)
warnings.filterwarnings("ignore", category=DeprecationWarning, message="info")
warnings.filterwarnings("ignore", category=DeprecationWarning, message="to_tuple")
# create_using for scale_free_graph
Expand Down
110 changes: 1 addition & 109 deletions networkx/convert_matrix.py
Expand Up @@ -39,7 +39,6 @@
"to_pandas_adjacency",
"from_pandas_edgelist",
"to_pandas_edgelist",
"to_numpy_recarray",
"from_scipy_sparse_array",
"from_scipy_sparse_matrix",
"to_scipy_sparse_array",
Expand Down Expand Up @@ -499,7 +498,7 @@ def to_numpy_matrix(
dtype : NumPy data type, optional
A valid single NumPy data type used to initialize the array.
This must be a simple type such as int or numpy.float64 and
not a compound data type (see to_numpy_recarray)
not a compound data type.
If None, then the NumPy default is used.

order : {'C', 'F'}, optional
Expand Down Expand Up @@ -527,10 +526,6 @@ def to_numpy_matrix(
M : NumPy matrix
Graph adjacency matrix

See Also
--------
to_numpy_recarray

Notes
-----
For directed graphs, entry i,j corresponds to an edge from i to j.
Expand Down Expand Up @@ -640,10 +635,6 @@ def from_numpy_matrix(A, parallel_edges=False, create_using=None):
of the data fields will be used as attribute keys in the resulting
NetworkX graph.

See Also
--------
to_numpy_recarray

Examples
--------
Simple integer weights on edges:
Expand Down Expand Up @@ -694,105 +685,6 @@ def from_numpy_matrix(A, parallel_edges=False, create_using=None):
return from_numpy_array(A, parallel_edges=parallel_edges, create_using=create_using)


@not_implemented_for("multigraph")
def to_numpy_recarray(G, nodelist=None, dtype=None, order=None):
"""Returns the graph adjacency matrix as a NumPy recarray.

.. deprecated:: 2.7

``to_numpy_recarray`` is deprecated and will be removed in NetworkX 3.0.
Use ``nx.to_numpy_array(G, dtype=dtype, weight=None).view(np.recarray)``
instead.

Parameters
----------
G : graph
The NetworkX graph used to construct the NumPy recarray.

nodelist : list, optional
The rows and columns are ordered according to the nodes in `nodelist`.
If `nodelist` is None, then the ordering is produced by G.nodes().

dtype : NumPy data-type, optional
A valid NumPy named dtype used to initialize the NumPy recarray.
The data type names are assumed to be keys in the graph edge attribute
dictionary. The default is ``dtype([("weight", float)])``.

order : {'C', 'F'}, optional
Whether to store multidimensional data in C- or Fortran-contiguous
(row- or column-wise) order in memory. If None, then the NumPy default
is used.

Returns
-------
M : NumPy recarray
The graph with specified edge data as a Numpy recarray

Notes
-----
When `nodelist` does not contain every node in `G`, the adjacency
matrix is built from the subgraph of `G` that is induced by the nodes in
`nodelist`.

Examples
--------
>>> G = nx.Graph()
>>> G.add_edge(1, 2, weight=7.0, cost=5)
>>> A = nx.to_numpy_recarray(G, dtype=[("weight", float), ("cost", int)])
>>> print(A.weight)
[[0. 7.]
[7. 0.]]
>>> print(A.cost)
[[0 5]
[5 0]]

"""
import warnings

import numpy as np

warnings.warn(
(
"to_numpy_recarray is deprecated and will be removed in version 3.0.\n"
"Use to_numpy_array instead::\n\n"
" nx.to_numpy_array(G, dtype=dtype, weight=None).view(np.recarray)"
),
DeprecationWarning,
stacklevel=2,
)

if dtype is None:
dtype = [("weight", float)]

if nodelist is None:
nodelist = list(G)
nodeset = G
nlen = len(G)
else:
nlen = len(nodelist)
nodeset = set(G.nbunch_iter(nodelist))
if nlen != len(nodeset):
for n in nodelist:
if n not in G:
raise nx.NetworkXError(f"Node {n} in nodelist is not in G")
raise nx.NetworkXError("nodelist contains duplicates.")

undirected = not G.is_directed()
index = dict(zip(nodelist, range(nlen)))
M = np.zeros((nlen, nlen), dtype=dtype, order=order)

names = M.dtype.names
for u, v, attrs in G.edges(data=True):
if (u in nodeset) and (v in nodeset):
i, j = index[u], index[v]
values = tuple(attrs[n] for n in names)
M[i, j] = values
if undirected:
M[j, i] = M[i, j]

return M.view(np.recarray)


def to_scipy_sparse_array(G, nodelist=None, dtype=None, weight="weight", format="csr"):
"""Returns the graph adjacency matrix as a SciPy sparse array.

Expand Down
83 changes: 0 additions & 83 deletions networkx/tests/test_convert_numpy.py
Expand Up @@ -16,10 +16,6 @@ def test_from_numpy_matrix_deprecation():
pytest.deprecated_call(nx.from_numpy_matrix, np.eye(2))


def test_to_numpy_recarray_deprecation():
pytest.deprecated_call(nx.to_numpy_recarray, nx.Graph())


class TestConvertNumpyMatrix:
# TODO: This entire class can be removed when to/from_numpy_matrix
# deprecation expires
Expand Down Expand Up @@ -171,16 +167,6 @@ def test_from_numpy_matrix_dtype(self):
assert G[0][0]["cost"] == 2
assert G[0][0]["weight"] == 1.0

def test_to_numpy_recarray(self):
G = nx.Graph()
G.add_edge(1, 2, weight=7.0, cost=5)
A = nx.to_numpy_recarray(G, dtype=[("weight", float), ("cost", int)])
assert sorted(A.dtype.names) == ["cost", "weight"]
assert A.weight[0, 1] == 7.0
assert A.weight[0, 0] == 0.0
assert A.cost[0, 1] == 5
assert A.cost[0, 0] == 0

def test_numpy_multigraph(self):
G = nx.MultiGraph()
G.add_edge(1, 2, weight=7)
Expand Down Expand Up @@ -434,75 +420,6 @@ def test_dtype_int_multigraph(self):
assert A.dtype == int


@pytest.fixture
def recarray_test_graph():
G = nx.Graph()
G.add_edge(1, 2, weight=7.0, cost=5)
return G


def test_to_numpy_recarray(recarray_test_graph):
A = nx.to_numpy_recarray(
recarray_test_graph, dtype=[("weight", float), ("cost", int)]
)
assert sorted(A.dtype.names) == ["cost", "weight"]
assert A.weight[0, 1] == 7.0
assert A.weight[0, 0] == 0.0
assert A.cost[0, 1] == 5
assert A.cost[0, 0] == 0
with pytest.raises(AttributeError, match="has no attribute"):
A.color[0, 1]


def test_to_numpy_recarray_default_dtype(recarray_test_graph):
A = nx.to_numpy_recarray(recarray_test_graph)
assert A.dtype.names == ("weight",)
assert A.weight[0, 0] == 0
assert A.weight[0, 1] == 7
with pytest.raises(AttributeError, match="has no attribute"):
A.cost[0, 1]


def test_to_numpy_recarray_directed(recarray_test_graph):
G = recarray_test_graph.to_directed()
G.remove_edge(2, 1)
A = nx.to_numpy_recarray(G, dtype=[("weight", float), ("cost", int)])
np.testing.assert_array_equal(A.weight, np.array([[0, 7.0], [0, 0]]))
np.testing.assert_array_equal(A.cost, np.array([[0, 5], [0, 0]]))


def test_to_numpy_recarray_default_dtype_no_weight():
G = nx.Graph()
G.add_edge(0, 1, color="red")
with pytest.raises(KeyError):
A = nx.to_numpy_recarray(G)
A = nx.to_numpy_recarray(G, dtype=[("color", "U8")])
assert A.color[0, 1] == "red"


@pytest.fixture
def recarray_nodelist_test_graph():
G = nx.Graph()
G.add_edges_from(
[(0, 1, {"weight": 1.0}), (0, 2, {"weight": 2.0}), (1, 2, {"weight": 0.5})]
)
return G


def test_to_numpy_recarray_nodelist(recarray_nodelist_test_graph):
A = nx.to_numpy_recarray(recarray_nodelist_test_graph, nodelist=[0, 1])
np.testing.assert_array_equal(A.weight, np.array([[0, 1], [1, 0]]))


@pytest.mark.parametrize(
("nodelist", "errmsg"),
(([2, 3], "in nodelist is not in G"), ([1, 1], "nodelist contains duplicates")),
)
def test_to_numpy_recarray_bad_nodelist(recarray_nodelist_test_graph, nodelist, errmsg):
with pytest.raises(nx.NetworkXError, match=errmsg):
A = nx.to_numpy_recarray(recarray_nodelist_test_graph, nodelist=nodelist)


@pytest.fixture
def multigraph_test_graph():
G = nx.MultiGraph()
Expand Down