summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/reference/convert.rst6
-rw-r--r--doc/release/release_dev.rst8
-rw-r--r--networkx/convert.py17
-rw-r--r--networkx/convert_matrix.py97
-rw-r--r--networkx/tests/test_convert_pandas.py22
5 files changed, 126 insertions, 24 deletions
diff --git a/doc/reference/convert.rst b/doc/reference/convert.rst
index ab72083d..78645b69 100644
--- a/doc/reference/convert.rst
+++ b/doc/reference/convert.rst
@@ -54,5 +54,7 @@ Pandas
.. autosummary::
:toctree: generated/
- to_pandas_dataframe
- from_pandas_dataframe
+ to_pandas_adjacency
+ from_pandas_adjacency
+ to_pandas_edgelist
+ from_pandas_edgelist
diff --git a/doc/release/release_dev.rst b/doc/release/release_dev.rst
index 1fe15399..627cf38d 100644
--- a/doc/release/release_dev.rst
+++ b/doc/release/release_dev.rst
@@ -192,6 +192,14 @@ API Changes
Deprecations
------------
+The following deprecated functions will be removed in 2.1.
+
+- The function ``bellman_ford`` has been deprecated in favor of
+ ``bellman_ford_predecessor_and_distance``.
+
+- The functions ``to_pandas_dataframe`` and ``from_pandas_dataframe`` have been
+ deprecated in favor of ``to_pandas_adjacency``, ``from_pandas_adjacency``,
+ ``to_pandas_edgelist``, and ``from_pandas_edgelist``.
Contributors to this release
----------------------------
diff --git a/networkx/convert.py b/networkx/convert.py
index e3a0b502..da639886 100644
--- a/networkx/convert.py
+++ b/networkx/convert.py
@@ -134,11 +134,18 @@ def to_networkx_graph(data, create_using=None, multigraph_input=False):
try:
import pandas as pd
if isinstance(data, pd.DataFrame):
- try:
- return nx.from_pandas_dataframe(data, edge_attr=True, create_using=create_using)
- except:
- msg = "Input is not a correct Pandas DataFrame."
- raise nx.NetworkXError(msg)
+ if data.shape[0] == data.shape[1]:
+ try:
+ return nx.from_pandas_adjacency(data, create_using=create_using)
+ except:
+ msg = "Input is not a correct Pandas DataFrame adjacency matrix."
+ raise nx.NetworkXError(msg)
+ else:
+ try:
+ return nx.from_pandas_edgelist(data, edge_attr=True, create_using=create_using)
+ except:
+ msg = "Input is not a correct Pandas DataFrame edge-list."
+ raise nx.NetworkXError(msg)
except ImportError:
msg = 'pandas not found, skipping conversion test.'
warnings.warn(msg, ImportWarning)
diff --git a/networkx/convert_matrix.py b/networkx/convert_matrix.py
index 69cbfba3..b0490f09 100644
--- a/networkx/convert_matrix.py
+++ b/networkx/convert_matrix.py
@@ -26,7 +26,7 @@ nx_agraph, nx_pydot
# Pieter Swart <swart@lanl.gov>
# All rights reserved.
# BSD license.
-import warnings
+import warnings as _warnings
import itertools
import networkx as nx
from networkx.convert import _prep_create_using
@@ -36,6 +36,8 @@ __author__ = """\n""".join(['Aric Hagberg <aric.hagberg@gmail.com>',
'Dan Schult(dschult@colgate.edu)'])
__all__ = ['from_numpy_matrix', 'to_numpy_matrix',
'from_pandas_dataframe', 'to_pandas_dataframe',
+ 'from_pandas_adjacency', 'to_pandas_adjacency',
+ 'from_pandas_edgelist', 'to_pandas_edgelist',
'to_numpy_recarray',
'from_scipy_sparse_matrix', 'to_scipy_sparse_matrix',
'from_numpy_array', 'to_numpy_array']
@@ -43,6 +45,15 @@ __all__ = ['from_numpy_matrix', 'to_numpy_matrix',
def to_pandas_dataframe(G, nodelist=None, dtype=None, order=None,
multigraph_weight=sum, weight='weight', nonedge=0.0):
+ """DEPRECATED: Replaced by ``to_pandas_adjacency``."""
+ msg = "to_pandas_dataframe is deprecated and will be removed" \
+ "in 2.1, use to_pandas_adjacency instead."
+ _warnings.warn(msg, DeprecationWarning)
+ return to_pandas_adjacency(G, nodelist, dtype, order, multigraph_weight, weight, nonedge)
+
+
+def to_pandas_adjacency(G, nodelist=None, dtype=None, order=None,
+ multigraph_weight=sum, weight='weight', nonedge=0.0):
"""Return the graph adjacency matrix as a Pandas DataFrame.
Parameters
@@ -94,7 +105,7 @@ def to_pandas_dataframe(G, nodelist=None, dtype=None, order=None,
>>> import pandas as pd
>>> import numpy as np
>>> G = nx.Graph([(1,1)])
- >>> df = nx.to_pandas_dataframe(G, dtype=int)
+ >>> df = nx.to_pandas_adjacency(G, dtype=int)
>>> df
1
1 1
@@ -114,7 +125,7 @@ def to_pandas_dataframe(G, nodelist=None, dtype=None, order=None,
0
>>> G.add_edge(2,2)
1
- >>> nx.to_pandas_dataframe(G, nodelist=[0,1,2], dtype=int)
+ >>> nx.to_pandas_adjacency(G, nodelist=[0,1,2], dtype=int)
0 1 2
0 0 2 0
1 1 0 0
@@ -129,8 +140,82 @@ def to_pandas_dataframe(G, nodelist=None, dtype=None, order=None,
return pd.DataFrame(data=M, index=nodelist, columns=nodelist)
+def from_pandas_adjacency(df, create_using=None):
+ """Return a graph from Pandas DataFrame.
+
+ The Pandas DataFrame is interpreted as an adjacency matrix for the graph.
+
+ Parameters
+ ----------
+ df : Pandas DataFrame
+ An adjacency matrix representation of a graph
+
+ create_using : NetworkX graph
+ Use specified graph for result. The default is Graph()
+
+ Notes
+ -----
+ If the numpy matrix has a single data type for each matrix entry it
+ will be converted to an appropriate Python data type.
+
+ If the numpy matrix has a user-specified compound data type the names
+ of the data fields will be used as attribute keys in the resulting
+ NetworkX graph.
+
+ See Also
+ --------
+ to_pandas_adjacency
+
+ Examples
+ --------
+ Simple integer weights on edges:
+
+ >>> import numpy as np
+ >>> import pandas as pd
+ >>> df = pd.DataFrame([[1, 1], [2, 1]])
+ >>> df
+ 0 1
+ 0 1 1
+ 1 2 1
+ >>> G = nx.from_pandas_adjacency(df)
+ >>> print(nx.info(G))
+ Name:
+ Type: Graph
+ Number of nodes: 2
+ Number of edges: 3
+ Average degree: 3.0000
+ """
+
+ A = df.values
+ G = from_numpy_matrix(A, create_using)
+ try:
+ df = df[df.index]
+ except:
+ raise nx.NetworkXError("Columns must match Indices.",
+ "%s not in columns"%list(set(df.index).difference(set(df.columns))))
+
+ nx.relabel.relabel_nodes(G, dict(enumerate(df.columns)), copy=False)
+ return G
+
+
+def to_pandas_edgelist(G, nodelist=None, dtype=None, order=None,
+ multigraph_weight=sum, weight='weight', nonedge=0.0):
+ """Placeholder
+ """
+ return NotImplemented
+
+
def from_pandas_dataframe(df, source='source', target='target', edge_attr=None,
create_using=None):
+ """DEPRECATED: Replaced by ``from_pandas_edgelist``."""
+ msg = "from_pandas_dataframe is deprecated and will be removed" \
+ "in 2.1, use from_pandas_edgelist instead."
+ _warnings.warn(msg, DeprecationWarning)
+ return from_pandas_edgelist(df, source, target, edge_attr, create_using)
+
+
+def from_pandas_edgelist(df, source='source', target='target', edge_attr=None,
+ create_using=None):
"""Return a graph from Pandas DataFrame containing an edge list.
The Pandas DataFrame should contain at least two columns of node names and
@@ -166,7 +251,7 @@ def from_pandas_dataframe(df, source='source', target='target', edge_attr=None,
See Also
--------
- to_pandas_dataframe
+ to_pandas_edgelist
Examples
--------
@@ -186,7 +271,7 @@ def from_pandas_dataframe(df, source='source', target='target', edge_attr=None,
0 4 7 A D
1 7 1 B A
2 10 9 C E
- >>> G=nx.from_pandas_dataframe(df, 0, 'b', ['weight', 'cost'])
+ >>> G=nx.from_pandas_edgelist(df, 0, 'b', ['weight', 'cost'])
>>> G['E']['C']['weight']
10
>>> G['E']['C']['cost']
@@ -195,7 +280,7 @@ def from_pandas_dataframe(df, source='source', target='target', edge_attr=None,
... 'target': [2, 2, 3],
... 'weight': [3, 4, 5],
... 'color': ['red', 'blue', 'blue']})
- >>> G = nx.from_pandas_dataframe(edges, edge_attr=True)
+ >>> G = nx.from_pandas_edgelist(edges, edge_attr=True)
>>> G[0][2]['color']
'red'
"""
diff --git a/networkx/tests/test_convert_pandas.py b/networkx/tests/test_convert_pandas.py
index 97a206d1..ed41c77d 100644
--- a/networkx/tests/test_convert_pandas.py
+++ b/networkx/tests/test_convert_pandas.py
@@ -34,40 +34,40 @@ class TestConvertPandas(object):
def assert_equal(self, G1, G2):
assert_true(nx.is_isomorphic(G1, G2, edge_match=lambda x, y: x == y))
- def test_from_dataframe_all_attr(self, ):
+ def test_from_edgelist_all_attr(self, ):
Gtrue = nx.Graph([('E', 'C', {'cost': 9, 'weight': 10}),
('B', 'A', {'cost': 1, 'weight': 7}),
('A', 'D', {'cost': 7, 'weight': 4})])
- G = nx.from_pandas_dataframe(self.df, 0, 'b', True)
+ G = nx.from_pandas_edgelist(self.df, 0, 'b', True)
self.assert_equal(G, Gtrue)
# MultiGraph
MGtrue = nx.MultiGraph(Gtrue)
MGtrue.add_edge('A', 'D', cost=16, weight=4)
- MG = nx.from_pandas_dataframe(self.mdf, 0, 'b', True, nx.MultiGraph())
+ MG = nx.from_pandas_edgelist(self.mdf, 0, 'b', True, nx.MultiGraph())
self.assert_equal(MG, MGtrue)
- def test_from_dataframe_multi_attr(self, ):
+ def test_from_edgelist_multi_attr(self, ):
Gtrue = nx.Graph([('E', 'C', {'cost': 9, 'weight': 10}),
('B', 'A', {'cost': 1, 'weight': 7}),
('A', 'D', {'cost': 7, 'weight': 4})])
- G = nx.from_pandas_dataframe(self.df, 0, 'b', ['weight', 'cost'])
+ G = nx.from_pandas_edgelist(self.df, 0, 'b', ['weight', 'cost'])
self.assert_equal(G, Gtrue)
- def test_from_dataframe_one_attr(self, ):
+ def test_from_edgelist_one_attr(self, ):
Gtrue = nx.Graph([('E', 'C', {'weight': 10}),
('B', 'A', {'weight': 7}),
('A', 'D', {'weight': 4})])
- G = nx.from_pandas_dataframe(self.df, 0, 'b', 'weight')
+ G = nx.from_pandas_edgelist(self.df, 0, 'b', 'weight')
self.assert_equal(G, Gtrue)
- def test_from_dataframe_no_attr(self, ):
+ def test_from_edgelist_no_attr(self, ):
Gtrue = nx.Graph([('E', 'C', {}),
('B', 'A', {}),
('A', 'D', {})])
- G = nx.from_pandas_dataframe(self.df, 0, 'b',)
+ G = nx.from_pandas_edgelist(self.df, 0, 'b',)
self.assert_equal(G, Gtrue)
- def test_from_datafram(self, ):
+ def test_from_edgelist(self, ):
# Pandas DataFrame
g = nx.cycle_graph(10)
G = nx.Graph()
@@ -81,7 +81,7 @@ class TestConvertPandas(object):
edges = pd.DataFrame({'source': source,
'target': target,
'weight': weight})
- GG = nx.from_pandas_dataframe(edges, edge_attr='weight')
+ GG = nx.from_pandas_edgelist(edges, edge_attr='weight')
assert_nodes_equal(sorted(G.nodes()), sorted(GG.nodes()))
assert_edges_equal(sorted(G.edges()), sorted(GG.edges()))
GW = nx.to_networkx_graph(edges, create_using=nx.Graph())