Repository: networkx/networkx

Issue:
to_pandas_dataframe is not the inverse of from_pandas_dataframe
The function `from_pandas_dataframe` assumes that the data frame has edge-list like structures, but `to_pandas_dataframe` generates an adjacency matrix. 

Personally, I think the edge-list like structures are more useful because:
(1) Otherwise these two functions are just (wrapped) duplications of `numpy_matrix` related functions
(2) The edge-list like data frames are convenient for other interfaces such as `py2cytoscape`. 

Some related commits:
[52eb3d3](https://github.com/networkx/networkx/commit/52eb3d38ff78e4002a424ae5e8976998afdaf1a2): `from_pandas_dataframe` and `to_pandas_dataframe` were added. At that time both functions were about adjacency matrix.  
[f0c22dd](https://github.com/networkx/networkx/commit/f0c22dd3305ff236860c651d8a08fbabcb8b0a77): `from_pandas_dataframe` was changed to current behavior, but it seems that `to_pandas_dataframe` was forgotten to be changed accordingly. 


Discussion:
As far as I can tell from the discussions on github this change may not have been intentional. 

It looks like we might need functions for pandas adjacency matrix as well as pandas edge list. Can anyone involved in the previous commits comment on the best way to fix this?
I don't use Pandas, but it also seems to me that there could be a use for both adjacency matrices and edge lists.  So maybe we should provide either (1) four functions or (2) modify the to/from functions to have a flag indicating whether we are using an adjacency matrix or an edge list.  I haven't looked at the code yet, but I am happy to provide an implementation of either solution.   @dschult , @hagberg 

If we go with 4 functions, maybe we should delete the two existing functions and provide something like:

```
def from_pandas_edgelist(df, source='source', target='target', edge_attr=None, create_using=None):

def to_pandas_edgelist(G, nodelist=None, dtype=None, order=None,
                                             multigraph_weight=sum, weight='weight', nonedge=0.0):

def from_pandas_adjacency(df, create_using=None, mask_zero=True, mask_nan=True):

def to_pandas_adjacency(G, nodelist=None, dtype=None, order=None,
                                                multigraph_weight=sum, weight='weight', nonedge=0.0):
```

Then in `to_networkx_graph`, we could do something like:

```
if isinstance(data, pd.DataFrame):
    if data.shape[0] == data.shape[1]:
        <call from_pandas_adjacency(data)
    else
         <call  from_pandas_edgelist(data, edge_attr=True, create_using=create_using)
```

Thoughts?  Should I try implementing something for comment?
I like the idea of explicit separate functions.

Yes, have a go at it!  :)  At the moment we have one written for adjacency and one written for edgelist. You can find the other edgelist in the history, but it might be just as well to rewrite it.   Have fun!

Resolving patch:
diff --git a/networkx/convert.py b/networkx/convert.py
--- a/networkx/convert.py
+++ b/networkx/convert.py
@@ -55,12 +55,12 @@ def to_networkx_graph(data, create_using=None, multigraph_input=False):
     The preferred way to call this is automatically
     from the class constructor
 
-    >>> d={0: {1: {'weight':1}}} # dict-of-dicts single edge (0,1)
-    >>> G=nx.Graph(d)
+    >>> d = {0: {1: {'weight':1}}} # dict-of-dicts single edge (0,1)
+    >>> G = nx.Graph(d)
 
     instead of the equivalent
 
-    >>> G=nx.from_dict_of_dicts(d)
+    >>> G = nx.from_dict_of_dicts(d)
 
     Parameters
     ----------
@@ -120,11 +120,9 @@ def to_networkx_graph(data, create_using=None, multigraph_input=False):
                 raise TypeError("Input is not known type.")
 
     # list or generator of edges
-    if (isinstance(data, list) or
-        isinstance(data, tuple) or
-        hasattr(data, '_adjdict') or
-        hasattr(data, 'next') or
-        hasattr(data, '__next__')):
+
+    if (isinstance(data, (list, tuple)) or
+            any(hasattr(data, attr) for attr in ['_adjdict', 'next', '__next__'])):
         try:
             return from_edgelist(data, create_using=create_using)
         except:
@@ -134,11 +132,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)
@@ -146,7 +151,7 @@ def to_networkx_graph(data, create_using=None, multigraph_input=False):
     # numpy matrix or ndarray
     try:
         import numpy
-        if isinstance(data, numpy.matrix) or isinstance(data, numpy.ndarray):
+        if isinstance(data, (numpy.matrix, numpy.ndarray)):
             try:
                 return nx.from_numpy_matrix(data, create_using=create_using)
             except:
@@ -172,8 +177,6 @@ def to_networkx_graph(data, create_using=None, multigraph_input=False):
     raise nx.NetworkXError(
         "Input is not a known data type for conversion.")
 
-    return
-
 
 def to_dict_of_lists(G, nodelist=None):
     """Return adjacency representation of graph as a dictionary of lists.
@@ -213,11 +216,12 @@ def from_dict_of_lists(d, create_using=None):
 
     Examples
     --------
-    >>> dol= {0:[1]} # single edge (0,1)
-    >>> G=nx.from_dict_of_lists(dol)
+    >>> dol = {0: [1]} # single edge (0,1)
+    >>> G = nx.from_dict_of_lists(dol)
 
     or
-    >>> G=nx.Graph(dol) # use Graph constructor
+
+    >>> G = nx.Graph(dol) # use Graph constructor
 
     """
     G = _prep_create_using(create_using)
@@ -296,11 +300,12 @@ def from_dict_of_dicts(d, create_using=None, multigraph_input=False):
 
     Examples
     --------
-    >>> dod= {0: {1:{'weight':1}}} # single edge (0,1)
-    >>> G=nx.from_dict_of_dicts(dod)
+    >>> dod = {0: {1: {'weight': 1}}} # single edge (0,1)
+    >>> G = nx.from_dict_of_dicts(dod)
 
     or
-    >>> G=nx.Graph(dod) # use Graph constructor
+
+    >>> G = nx.Graph(dod) # use Graph constructor
 
     """
     G = _prep_create_using(create_using)
@@ -314,13 +319,13 @@ def from_dict_of_dicts(d, create_using=None, multigraph_input=False):
                                  for u, nbrs in d.items()
                                  for v, datadict in nbrs.items()
                                  for key, data in datadict.items()
-                                 )
+                                )
             else:
                 G.add_edges_from((u, v, data)
                                  for u, nbrs in d.items()
                                  for v, datadict in nbrs.items()
                                  for key, data in datadict.items()
-                                 )
+                                )
         else:  # Undirected
             if G.is_multigraph():
                 seen = set()   # don't add both directions of undirected graph
@@ -329,7 +334,7 @@ def from_dict_of_dicts(d, create_using=None, multigraph_input=False):
                         if (u, v) not in seen:
                             G.add_edges_from((u, v, key, data)
                                              for key, data in datadict.items()
-                                             )
+                                            )
                             seen.add((v, u))
             else:
                 seen = set()   # don't add both directions of undirected graph
@@ -373,8 +378,7 @@ def to_edgelist(G, nodelist=None):
     """
     if nodelist is None:
         return G.edges(data=True)
-    else:
-        return G.edges(nodelist, data=True)
+    return G.edges(nodelist, data=True)
 
 
 def from_edgelist(edgelist, create_using=None):
@@ -390,11 +394,12 @@ def from_edgelist(edgelist, create_using=None):
 
     Examples
     --------
-    >>> edgelist= [(0,1)] # single edge (0,1)
-    >>> G=nx.from_edgelist(edgelist)
+    >>> edgelist = [(0, 1)] # single edge (0,1)
+    >>> G = nx.from_edgelist(edgelist)
 
     or
-    >>> G=nx.Graph(edgelist) # use Graph constructor
+
+    >>> G = nx.Graph(edgelist) # use Graph constructor
 
     """
     G = _prep_create_using(create_using)
diff --git a/networkx/convert_matrix.py b/networkx/convert_matrix.py
--- a/networkx/convert_matrix.py
+++ b/networkx/convert_matrix.py
@@ -1,3 +1,9 @@
+#    Copyright (C) 2006-2017 by
+#    Aric Hagberg <hagberg@lanl.gov>
+#    Dan Schult <dschult@colgate.edu>
+#    Pieter Swart <swart@lanl.gov>
+#    All rights reserved.
+#    BSD license.
 """Functions to convert NetworkX graphs to and from numpy/scipy matrices.
 
 The preferred way of converting data to a NetworkX graph is through the
@@ -8,34 +14,29 @@
 --------
 Create a 10 node random graph from a numpy matrix
 
->>> import numpy
->>> a = numpy.reshape(numpy.random.random_integers(0,1,size=100),(10,10))
+>>> import numpy as np
+>>> a = np.reshape(np.random.random_integers(0, 1, size=100), (10, 10))
 >>> D = nx.DiGraph(a)
 
 or equivalently
 
->>> D = nx.to_networkx_graph(a,create_using=nx.DiGraph())
+>>> D = nx.to_networkx_graph(a, create_using=nx.DiGraph())
 
 See Also
 --------
 nx_agraph, nx_pydot
 """
-#    Copyright (C) 2006-2014 by
-#    Aric Hagberg <hagberg@lanl.gov>
-#    Dan Schult <dschult@colgate.edu>
-#    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
 from networkx.utils import not_implemented_for
-__author__ = """\n""".join(['Aric Hagberg <aric.hagberg@gmail.com>',
-                            'Pieter Swart (swart@lanl.gov)',
-                            '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 +44,15 @@
 
 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
@@ -93,8 +103,8 @@ 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)
+    >>> G = nx.Graph([(1, 1)])
+    >>> df = nx.to_pandas_adjacency(G, dtype=int)
     >>> df
        1
     1  1
@@ -106,19 +116,20 @@ def to_pandas_dataframe(G, nodelist=None, dtype=None, order=None,
     Examples
     --------
     >>> G = nx.MultiDiGraph()
-    >>> G.add_edge(0,1,weight=2)
+    >>> G.add_edge(0, 1, weight=2)
     0
-    >>> G.add_edge(1,0)
+    >>> G.add_edge(1, 0)
     0
-    >>> G.add_edge(2,2,weight=3)
+    >>> G.add_edge(2, 2, weight=3)
     0
-    >>> G.add_edge(2,2)
+    >>> 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
     2  0  0  4
+
     """
     import pandas as pd
     M = to_numpy_matrix(G, nodelist=nodelist, dtype=dtype, order=order,
@@ -129,8 +140,125 @@ 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):
+    r"""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 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, source='source', target='target', nodelist=None,
+                       dtype=None, order=None):
+    """Return the graph edge list as a Pandas DataFrame.
+
+    Parameters
+    ----------
+    G : graph
+        The NetworkX graph used to construct the Pandas DataFrame.
+
+    source : str or int, optional
+        A valid column name (string or iteger) for the source nodes (for the
+        directed case).
+
+    target : str or int, optional
+        A valid column name (string or iteger) for the target nodes (for the
+        directed case).
+
+    nodelist : list, optional
+       Use only nodes specified in nodelist
+
+    Returns
+    -------
+    df : Pandas DataFrame
+       Graph edge list
+
+    Examples
+    --------
+    >>> G = nx.Graph([('A', 'B', {'cost': 1, 'weight': 7}),
+    ...               ('C', 'E', {'cost': 9, 'weight': 10})])
+    >>> df = nx.to_pandas_edgelist(G, nodelist=['A', 'C'])
+    >>> df
+       cost source target  weight
+    0     1      A      B       7
+    1     9      C      E      10
+
+    """
+    import pandas as pd
+    if nodelist is None:
+        edgelist = G.edges(data=True)
+    else:
+        edgelist = G.edges(nodelist, data=True)
+    source_nodes = [s for s, t, d in edgelist]
+    target_nodes = [t for s, t, d in edgelist]
+    all_keys = set().union(*(d.keys() for s, t, d in edgelist))
+    edge_attr = {k: [d.get(k, float("nan")) for s, t, d in edgelist] for k in all_keys}
+    edgelistdict = {source: source_nodes, target: target_nodes}
+    edgelistdict.update(edge_attr)
+    return pd.DataFrame(edgelistdict)
+
+
 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 +294,7 @@ def from_pandas_dataframe(df, source='source', target='target', edge_attr=None,
 
     See Also
     --------
-    to_pandas_dataframe
+    to_pandas_edgelist
 
     Examples
     --------
@@ -186,7 +314,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,9 +323,10 @@ 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'
+
     """
 
     g = _prep_create_using(create_using)
@@ -317,18 +446,19 @@ def to_numpy_matrix(G, nodelist=None, dtype=None, order=None,
     Examples
     --------
     >>> G = nx.MultiDiGraph()
-    >>> G.add_edge(0,1,weight=2)
+    >>> G.add_edge(0, 1, weight=2)
     0
-    >>> G.add_edge(1,0)
+    >>> G.add_edge(1, 0)
     0
-    >>> G.add_edge(2,2,weight=3)
+    >>> G.add_edge(2, 2, weight=3)
     0
-    >>> G.add_edge(2,2)
+    >>> G.add_edge(2, 2)
     1
-    >>> nx.to_numpy_matrix(G, nodelist=[0,1,2])
+    >>> nx.to_numpy_matrix(G, nodelist=[0, 1, 2])
     matrix([[ 0.,  2.,  0.],
             [ 1.,  0.,  0.],
             [ 0.,  0.,  4.]])
+
     """
     import numpy as np
 
@@ -385,17 +515,16 @@ def from_numpy_matrix(A, parallel_edges=False, create_using=None):
     --------
     Simple integer weights on edges:
 
-    >>> import numpy
-    >>> A=numpy.matrix([[1, 1], [2, 1]])
-    >>> G=nx.from_numpy_matrix(A)
+    >>> import numpy as np
+    >>> A = np.matrix([[1, 1], [2, 1]])
+    >>> G = nx.from_numpy_matrix(A)
 
     If `create_using` is a multigraph and the matrix has only integer entries,
     the entries will be interpreted as weighted edges joining the vertices
     (without creating parallel edges):
 
-    >>> import numpy
-    >>> A = numpy.matrix([[1, 1], [1, 2]])
-    >>> G = nx.from_numpy_matrix(A, create_using = nx.MultiGraph())
+    >>> A = np.matrix([[1, 1], [1, 2]])
+    >>> G = nx.from_numpy_matrix(A, create_using=nx.MultiGraph())
     >>> G[1][1]
     AtlasView({0: {'weight': 2}})
 
@@ -403,18 +532,16 @@ def from_numpy_matrix(A, parallel_edges=False, create_using=None):
     but `parallel_edges` is True, then the entries will be interpreted as
     the number of parallel edges joining those two vertices:
 
-    >>> import numpy
-    >>> A = numpy.matrix([[1, 1], [1, 2]])
+    >>> A = np.matrix([[1, 1], [1, 2]])
     >>> temp = nx.MultiGraph()
-    >>> G = nx.from_numpy_matrix(A, parallel_edges = True, create_using = temp)
+    >>> G = nx.from_numpy_matrix(A, parallel_edges=True, create_using=temp)
     >>> G[1][1]
     AtlasView({0: {'weight': 1}, 1: {'weight': 1}})
 
     User defined compound data type on edges:
 
-    >>> import numpy
     >>> dt = [('weight', float), ('cost', int)]
-    >>> A = numpy.matrix([[(1.0, 2)]], dtype = dt)
+    >>> A = np.matrix([[(1.0, 2)]], dtype=dt)
     >>> G = nx.from_numpy_matrix(A)
     >>> list(G.edges())
     [(0, 0)]
@@ -436,7 +563,7 @@ def from_numpy_matrix(A, parallel_edges=False, create_using=None):
     try:  # Python 3.x
         blurb = chr(1245)  # just to trigger the exception
         kind_to_python_type['U'] = str
-    except ValueError:  # Python 2.6+
+    except ValueError:  # Python 2.7
         kind_to_python_type['U'] = unicode
     G = _prep_create_using(create_using)
     n, m = A.shape
@@ -530,14 +657,15 @@ def to_numpy_recarray(G, nodelist=None, dtype=None, order=None):
     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)])
+    >>> 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]]
+
     """
     if dtype is None:
         dtype = [('weight', float)]
@@ -617,26 +745,26 @@ def to_scipy_sparse_matrix(G, nodelist=None, dtype=None,
     resulting Scipy sparse matrix can be modified as follows:
 
     >>> import scipy as sp
-    >>> G = nx.Graph([(1,1)])
+    >>> G = nx.Graph([(1, 1)])
     >>> A = nx.to_scipy_sparse_matrix(G)
     >>> print(A.todense())
     [[1]]
-    >>> A.setdiag(A.diagonal()*2)
+    >>> A.setdiag(A.diagonal() * 2)
     >>> print(A.todense())
     [[2]]
 
     Examples
     --------
     >>> G = nx.MultiDiGraph()
-    >>> G.add_edge(0,1,weight=2)
+    >>> G.add_edge(0, 1, weight=2)
     0
-    >>> G.add_edge(1,0)
+    >>> G.add_edge(1, 0)
     0
-    >>> G.add_edge(2,2,weight=3)
+    >>> G.add_edge(2, 2, weight=3)
     0
-    >>> G.add_edge(2,2)
+    >>> G.add_edge(2, 2)
     1
-    >>> S = nx.to_scipy_sparse_matrix(G, nodelist=[0,1,2])
+    >>> S = nx.to_scipy_sparse_matrix(G, nodelist=[0, 1, 2])
     >>> print(S.todense())
     [[0 2 0]
      [1 0 0]
@@ -791,16 +919,15 @@ def from_scipy_sparse_matrix(A, parallel_edges=False, create_using=None,
 
     Examples
     --------
-    >>> import scipy.sparse
-    >>> A = scipy.sparse.eye(2,2,1)
+    >>> import scipy as sp
+    >>> A = sp.sparse.eye(2, 2, 1)
     >>> G = nx.from_scipy_sparse_matrix(A)
 
     If `create_using` is a multigraph and the matrix has only integer entries,
     the entries will be interpreted as weighted edges joining the vertices
     (without creating parallel edges):
 
-    >>> import scipy
-    >>> A = scipy.sparse.csr_matrix([[1, 1], [1, 2]])
+    >>> A = sp.sparse.csr_matrix([[1, 1], [1, 2]])
     >>> G = nx.from_scipy_sparse_matrix(A, create_using=nx.MultiGraph())
     >>> G[1][1]
     AtlasView({0: {'weight': 2}})
@@ -809,8 +936,7 @@ def from_scipy_sparse_matrix(A, parallel_edges=False, create_using=None,
     but `parallel_edges` is True, then the entries will be interpreted as
     the number of parallel edges joining those two vertices:
 
-    >>> import scipy
-    >>> A = scipy.sparse.csr_matrix([[1, 1], [1, 2]])
+    >>> A = sp.sparse.csr_matrix([[1, 1], [1, 2]])
     >>> G = nx.from_scipy_sparse_matrix(A, parallel_edges=True,
     ...                                 create_using=nx.MultiGraph())
     >>> G[1][1]
@@ -932,18 +1058,19 @@ def to_numpy_array(G, nodelist=None, dtype=None, order=None,
     Examples
     --------
     >>> G = nx.MultiDiGraph()
-    >>> G.add_edge(0,1,weight=2)
+    >>> G.add_edge(0, 1, weight=2)
     0
-    >>> G.add_edge(1,0)
+    >>> G.add_edge(1, 0)
     0
-    >>> G.add_edge(2,2,weight=3)
+    >>> G.add_edge(2, 2, weight=3)
     0
-    >>> G.add_edge(2,2)
+    >>> G.add_edge(2, 2)
     1
-    >>> nx.to_numpy_array(G, nodelist=[0,1,2])
+    >>> nx.to_numpy_array(G, nodelist=[0, 1, 2])
     array([[ 0.,  2.,  0.],
            [ 1.,  0.,  0.],
            [ 0.,  0.,  4.]])
+
     """
     import numpy as np
     if nodelist is None:
@@ -1080,7 +1207,6 @@ def from_numpy_array(A, parallel_edges=False, create_using=None):
     the entries will be interpreted as weighted edges joining the vertices
     (without creating parallel edges):
 
-    >>> import numpy as np
     >>> A = np.array([[1, 1], [1, 2]])
     >>> G = nx.from_numpy_array(A, create_using=nx.MultiGraph())
     >>> G[1][1]
@@ -1090,7 +1216,6 @@ def from_numpy_array(A, parallel_edges=False, create_using=None):
     but `parallel_edges` is True, then the entries will be interpreted as
     the number of parallel edges joining those two vertices:
 
-    >>> import numpy as np
     >>> A = np.array([[1, 1], [1, 2]])
     >>> temp = nx.MultiGraph()
     >>> G = nx.from_numpy_array(A, parallel_edges=True, create_using=temp)
@@ -1099,7 +1224,6 @@ def from_numpy_array(A, parallel_edges=False, create_using=None):
 
     User defined compound data type on edges:
 
-    >>> import numpy
     >>> dt = [('weight', float), ('cost', int)]
     >>> A = np.array([[(1.0, 2)]], dtype=dt)
     >>> G = nx.from_numpy_array(A)


Test patch:
diff --git a/networkx/tests/test_convert.py b/networkx/tests/test_convert.py
--- a/networkx/tests/test_convert.py
+++ b/networkx/tests/test_convert.py
@@ -1,5 +1,7 @@
 #!/usr/bin/env python
-from nose.tools import assert_equal, assert_not_equal, assert_true, assert_false
+from nose.tools import (assert_equal, assert_not_equal,
+                        assert_true, assert_false,
+                        assert_raises)
 
 import networkx as nx
 from networkx.testing import assert_nodes_equal, assert_edges_equal, assert_graphs_equal
@@ -39,6 +41,38 @@ def test_simple_graphs(self):
             Gdod = nx.Graph(dod)
             assert_graphs_equal(Gdod, P3)
 
+    def test_exceptions(self):
+        # _prep_create_using
+        G = {"a": "a"}
+        H = nx.to_networkx_graph(G)
+        assert_graphs_equal(H, nx.Graph([('a', 'a')]))
+        assert_raises(TypeError, to_networkx_graph, G, create_using=0.0)
+
+        # NX graph
+        class G(object):
+            adj = None
+
+        assert_raises(nx.NetworkXError, to_networkx_graph, G)
+
+        # pygraphviz  agraph
+        class G(object):
+            is_strict = None
+
+        assert_raises(nx.NetworkXError, to_networkx_graph, G)
+
+        # Dict of [dicts, lists]
+        G = {"a": 0}
+        assert_raises(TypeError, to_networkx_graph, G)
+
+        # list or generator of edges
+        class G(object):
+            next = None
+
+        assert_raises(nx.NetworkXError, to_networkx_graph, G)
+
+        # no match
+        assert_raises(nx.NetworkXError, to_networkx_graph, "a")
+
     def test_digraphs(self):
         for dest, source in [(to_dict_of_dicts, from_dict_of_dicts),
                              (to_dict_of_lists, from_dict_of_lists)]:
@@ -225,3 +259,8 @@ def test_attribute_dict_integrity(self):
         assert_equal(list(H.nodes), list(G.nodes))
         H = nx.OrderedDiGraph(G)
         assert_equal(list(H.nodes), list(G.nodes))
+
+    def test_to_edgelist(self):
+        G = nx.Graph([(1, 1)])
+        elist = nx.to_edgelist(G, nodelist=list(G))
+        assert_edges_equal(G.edges(data=True), elist)
diff --git a/networkx/tests/test_convert_numpy.py b/networkx/tests/test_convert_numpy.py
--- a/networkx/tests/test_convert_numpy.py
+++ b/networkx/tests/test_convert_numpy.py
@@ -2,19 +2,20 @@
 from nose.tools import assert_raises, assert_true, assert_equal
 
 import networkx as nx
-from networkx.generators.classic import barbell_graph,cycle_graph,path_graph
+from networkx.generators.classic import barbell_graph, cycle_graph, path_graph
 from networkx.testing.utils import assert_graphs_equal
 
 
 class TestConvertNumpy(object):
-    numpy=1 # nosetests attribute, use nosetests -a 'not numpy' to skip test
+    numpy = 1  # nosetests attribute, use nosetests -a 'not numpy' to skip test
+
     @classmethod
     def setupClass(cls):
         global np
         global np_assert_equal
         try:
             import numpy as np
-            np_assert_equal=np.testing.assert_equal
+            np_assert_equal = np.testing.assert_equal
         except ImportError:
             raise SkipTest('NumPy not available.')
 
@@ -25,15 +26,19 @@ def __init__(self):
         self.G3 = self.create_weighted(nx.Graph())
         self.G4 = self.create_weighted(nx.DiGraph())
 
+    def test_exceptions(self):
+        G = np.array("a")
+        assert_raises(nx.NetworkXError, nx.to_networkx_graph, G)
+
     def create_weighted(self, G):
         g = cycle_graph(4)
         G.add_nodes_from(g)
-        G.add_weighted_edges_from( (u,v,10+u) for u,v in g.edges())
+        G.add_weighted_edges_from((u, v, 10 + u) for u, v in g.edges())
         return G
 
     def assert_equal(self, G1, G2):
-        assert_true( sorted(G1.nodes())==sorted(G2.nodes()) )
-        assert_true( sorted(G1.edges())==sorted(G2.edges()) )
+        assert_true(sorted(G1.nodes()) == sorted(G2.nodes()))
+        assert_true(sorted(G1.edges()) == sorted(G2.edges()))
 
     def identity_conversion(self, G, A, create_using):
         assert(A.sum() > 0)
@@ -46,7 +51,7 @@ def identity_conversion(self, G, A, create_using):
 
     def test_shape(self):
         "Conversion from non-square array."
-        A=np.array([[1,2,3],[4,5,6]])
+        A = np.array([[1, 2, 3], [4, 5, 6]])
         assert_raises(nx.NetworkXError, nx.from_numpy_matrix, A)
 
     def test_identity_graph_matrix(self):
@@ -108,66 +113,66 @@ def test_nodelist(self):
 
     def test_weight_keyword(self):
         WP4 = nx.Graph()
-        WP4.add_edges_from( (n,n+1,dict(weight=0.5,other=0.3)) for n in range(3) )
+        WP4.add_edges_from((n, n + 1, dict(weight=0.5, other=0.3)) for n in range(3))
         P4 = path_graph(4)
         A = nx.to_numpy_matrix(P4)
-        np_assert_equal(A, nx.to_numpy_matrix(WP4,weight=None))
-        np_assert_equal(0.5*A, nx.to_numpy_matrix(WP4))
-        np_assert_equal(0.3*A, nx.to_numpy_matrix(WP4,weight='other'))
+        np_assert_equal(A, nx.to_numpy_matrix(WP4, weight=None))
+        np_assert_equal(0.5 * A, nx.to_numpy_matrix(WP4))
+        np_assert_equal(0.3 * A, nx.to_numpy_matrix(WP4, weight='other'))
 
     def test_from_numpy_matrix_type(self):
-        A=np.matrix([[1]])
-        G=nx.from_numpy_matrix(A)
-        assert_equal(type(G[0][0]['weight']),int)
+        A = np.matrix([[1]])
+        G = nx.from_numpy_matrix(A)
+        assert_equal(type(G[0][0]['weight']), int)
 
-        A=np.matrix([[1]]).astype(np.float)
-        G=nx.from_numpy_matrix(A)
-        assert_equal(type(G[0][0]['weight']),float)
+        A = np.matrix([[1]]).astype(np.float)
+        G = nx.from_numpy_matrix(A)
+        assert_equal(type(G[0][0]['weight']), float)
 
-        A=np.matrix([[1]]).astype(np.str)
-        G=nx.from_numpy_matrix(A)
-        assert_equal(type(G[0][0]['weight']),str)
+        A = np.matrix([[1]]).astype(np.str)
+        G = nx.from_numpy_matrix(A)
+        assert_equal(type(G[0][0]['weight']), str)
 
-        A=np.matrix([[1]]).astype(np.bool)
-        G=nx.from_numpy_matrix(A)
-        assert_equal(type(G[0][0]['weight']),bool)
+        A = np.matrix([[1]]).astype(np.bool)
+        G = nx.from_numpy_matrix(A)
+        assert_equal(type(G[0][0]['weight']), bool)
 
-        A=np.matrix([[1]]).astype(np.complex)
-        G=nx.from_numpy_matrix(A)
-        assert_equal(type(G[0][0]['weight']),complex)
+        A = np.matrix([[1]]).astype(np.complex)
+        G = nx.from_numpy_matrix(A)
+        assert_equal(type(G[0][0]['weight']), complex)
 
-        A=np.matrix([[1]]).astype(np.object)
-        assert_raises(TypeError,nx.from_numpy_matrix,A)
+        A = np.matrix([[1]]).astype(np.object)
+        assert_raises(TypeError, nx.from_numpy_matrix, A)
 
     def test_from_numpy_matrix_dtype(self):
-        dt=[('weight',float),('cost',int)]
-        A=np.matrix([[(1.0,2)]],dtype=dt)
-        G=nx.from_numpy_matrix(A)
-        assert_equal(type(G[0][0]['weight']),float)
-        assert_equal(type(G[0][0]['cost']),int)
-        assert_equal(G[0][0]['cost'],2)
-        assert_equal(G[0][0]['weight'],1.0)
+        dt = [('weight', float), ('cost', int)]
+        A = np.matrix([[(1.0, 2)]], dtype=dt)
+        G = nx.from_numpy_matrix(A)
+        assert_equal(type(G[0][0]['weight']), float)
+        assert_equal(type(G[0][0]['cost']), int)
+        assert_equal(G[0][0]['cost'], 2)
+        assert_equal(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_equal(sorted(A.dtype.names),['cost','weight'])
-        assert_equal(A.weight[0,1],7.0)
-        assert_equal(A.weight[0,0],0.0)
-        assert_equal(A.cost[0,1],5)
-        assert_equal(A.cost[0,0],0)
+        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_equal(sorted(A.dtype.names), ['cost', 'weight'])
+        assert_equal(A.weight[0, 1], 7.0)
+        assert_equal(A.weight[0, 0], 0.0)
+        assert_equal(A.cost[0, 1], 5)
+        assert_equal(A.cost[0, 0], 0)
 
     def test_numpy_multigraph(self):
-        G=nx.MultiGraph()
-        G.add_edge(1,2,weight=7)
-        G.add_edge(1,2,weight=70)
-        A=nx.to_numpy_matrix(G)
-        assert_equal(A[1,0],77)
-        A=nx.to_numpy_matrix(G,multigraph_weight=min)
-        assert_equal(A[1,0],7)
-        A=nx.to_numpy_matrix(G,multigraph_weight=max)
-        assert_equal(A[1,0],70)
+        G = nx.MultiGraph()
+        G.add_edge(1, 2, weight=7)
+        G.add_edge(1, 2, weight=70)
+        A = nx.to_numpy_matrix(G)
+        assert_equal(A[1, 0], 77)
+        A = nx.to_numpy_matrix(G, multigraph_weight=min)
+        assert_equal(A[1, 0], 7)
+        A = nx.to_numpy_matrix(G, multigraph_weight=max)
+        assert_equal(A[1, 0], 70)
 
     def test_from_numpy_matrix_parallel_edges(self):
         """Tests that the :func:`networkx.from_numpy_matrix` function
@@ -238,14 +243,15 @@ def test_dtype_int_multigraph(self):
 
 
 class TestConvertNumpyArray(object):
-    numpy=1 # nosetests attribute, use nosetests -a 'not numpy' to skip test
+    numpy = 1  # nosetests attribute, use nosetests -a 'not numpy' to skip test
+
     @classmethod
     def setupClass(cls):
         global np
         global np_assert_equal
         try:
             import numpy as np
-            np_assert_equal=np.testing.assert_equal
+            np_assert_equal = np.testing.assert_equal
         except ImportError:
             raise SkipTest('NumPy not available.')
 
@@ -259,12 +265,12 @@ def __init__(self):
     def create_weighted(self, G):
         g = cycle_graph(4)
         G.add_nodes_from(g)
-        G.add_weighted_edges_from( (u,v,10+u) for u,v in g.edges())
+        G.add_weighted_edges_from((u, v, 10 + u) for u, v in g.edges())
         return G
 
     def assert_equal(self, G1, G2):
-        assert_true( sorted(G1.nodes())==sorted(G2.nodes()) )
-        assert_true( sorted(G1.edges())==sorted(G2.edges()) )
+        assert_true(sorted(G1.nodes()) == sorted(G2.nodes()))
+        assert_true(sorted(G1.edges()) == sorted(G2.edges()))
 
     def identity_conversion(self, G, A, create_using):
         assert(A.sum() > 0)
@@ -277,7 +283,7 @@ def identity_conversion(self, G, A, create_using):
 
     def test_shape(self):
         "Conversion from non-square array."
-        A=np.array([[1,2,3],[4,5,6]])
+        A = np.array([[1, 2, 3], [4, 5, 6]])
         assert_raises(nx.NetworkXError, nx.from_numpy_array, A)
 
     def test_identity_graph_array(self):
@@ -315,66 +321,66 @@ def test_nodelist(self):
 
     def test_weight_keyword(self):
         WP4 = nx.Graph()
-        WP4.add_edges_from( (n,n+1,dict(weight=0.5,other=0.3)) for n in range(3) )
+        WP4.add_edges_from((n, n + 1, dict(weight=0.5, other=0.3)) for n in range(3))
         P4 = path_graph(4)
         A = nx.to_numpy_array(P4)
-        np_assert_equal(A, nx.to_numpy_array(WP4,weight=None))
-        np_assert_equal(0.5*A, nx.to_numpy_array(WP4))
-        np_assert_equal(0.3*A, nx.to_numpy_array(WP4,weight='other'))
+        np_assert_equal(A, nx.to_numpy_array(WP4, weight=None))
+        np_assert_equal(0.5 * A, nx.to_numpy_array(WP4))
+        np_assert_equal(0.3 * A, nx.to_numpy_array(WP4, weight='other'))
 
     def test_from_numpy_array_type(self):
-        A=np.array([[1]])
-        G=nx.from_numpy_array(A)
-        assert_equal(type(G[0][0]['weight']),int)
+        A = np.array([[1]])
+        G = nx.from_numpy_array(A)
+        assert_equal(type(G[0][0]['weight']), int)
 
-        A=np.array([[1]]).astype(np.float)
-        G=nx.from_numpy_array(A)
-        assert_equal(type(G[0][0]['weight']),float)
+        A = np.array([[1]]).astype(np.float)
+        G = nx.from_numpy_array(A)
+        assert_equal(type(G[0][0]['weight']), float)
 
-        A=np.array([[1]]).astype(np.str)
-        G=nx.from_numpy_array(A)
-        assert_equal(type(G[0][0]['weight']),str)
+        A = np.array([[1]]).astype(np.str)
+        G = nx.from_numpy_array(A)
+        assert_equal(type(G[0][0]['weight']), str)
 
-        A=np.array([[1]]).astype(np.bool)
-        G=nx.from_numpy_array(A)
-        assert_equal(type(G[0][0]['weight']),bool)
+        A = np.array([[1]]).astype(np.bool)
+        G = nx.from_numpy_array(A)
+        assert_equal(type(G[0][0]['weight']), bool)
 
-        A=np.array([[1]]).astype(np.complex)
-        G=nx.from_numpy_array(A)
-        assert_equal(type(G[0][0]['weight']),complex)
+        A = np.array([[1]]).astype(np.complex)
+        G = nx.from_numpy_array(A)
+        assert_equal(type(G[0][0]['weight']), complex)
 
-        A=np.array([[1]]).astype(np.object)
-        assert_raises(TypeError,nx.from_numpy_array,A)
+        A = np.array([[1]]).astype(np.object)
+        assert_raises(TypeError, nx.from_numpy_array, A)
 
     def test_from_numpy_array_dtype(self):
-        dt=[('weight',float),('cost',int)]
-        A=np.array([[(1.0,2)]],dtype=dt)
-        G=nx.from_numpy_array(A)
-        assert_equal(type(G[0][0]['weight']),float)
-        assert_equal(type(G[0][0]['cost']),int)
-        assert_equal(G[0][0]['cost'],2)
-        assert_equal(G[0][0]['weight'],1.0)
+        dt = [('weight', float), ('cost', int)]
+        A = np.array([[(1.0, 2)]], dtype=dt)
+        G = nx.from_numpy_array(A)
+        assert_equal(type(G[0][0]['weight']), float)
+        assert_equal(type(G[0][0]['cost']), int)
+        assert_equal(G[0][0]['cost'], 2)
+        assert_equal(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_equal(sorted(A.dtype.names),['cost','weight'])
-        assert_equal(A.weight[0,1],7.0)
-        assert_equal(A.weight[0,0],0.0)
-        assert_equal(A.cost[0,1],5)
-        assert_equal(A.cost[0,0],0)
+        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_equal(sorted(A.dtype.names), ['cost', 'weight'])
+        assert_equal(A.weight[0, 1], 7.0)
+        assert_equal(A.weight[0, 0], 0.0)
+        assert_equal(A.cost[0, 1], 5)
+        assert_equal(A.cost[0, 0], 0)
 
     def test_numpy_multigraph(self):
-        G=nx.MultiGraph()
-        G.add_edge(1,2,weight=7)
-        G.add_edge(1,2,weight=70)
-        A=nx.to_numpy_array(G)
-        assert_equal(A[1,0],77)
-        A=nx.to_numpy_array(G,multigraph_weight=min)
-        assert_equal(A[1,0],7)
-        A=nx.to_numpy_array(G,multigraph_weight=max)
-        assert_equal(A[1,0],70)
+        G = nx.MultiGraph()
+        G.add_edge(1, 2, weight=7)
+        G.add_edge(1, 2, weight=70)
+        A = nx.to_numpy_array(G)
+        assert_equal(A[1, 0], 77)
+        A = nx.to_numpy_array(G, multigraph_weight=min)
+        assert_equal(A[1, 0], 7)
+        A = nx.to_numpy_array(G, multigraph_weight=max)
+        assert_equal(A[1, 0], 70)
 
     def test_from_numpy_array_parallel_edges(self):
         """Tests that the :func:`networkx.from_numpy_array` function
@@ -390,10 +396,10 @@ def test_from_numpy_array_parallel_edges(self):
         expected.add_weighted_edges_from([(u, v, 1) for (u, v) in edges])
         expected.add_edge(1, 1, weight=2)
         actual = nx.from_numpy_array(A, parallel_edges=True,
-                                      create_using=nx.DiGraph())
+                                     create_using=nx.DiGraph())
         assert_graphs_equal(actual, expected)
         actual = nx.from_numpy_array(A, parallel_edges=False,
-                                      create_using=nx.DiGraph())
+                                     create_using=nx.DiGraph())
         assert_graphs_equal(actual, expected)
         # Now each integer entry in the adjacency matrix is interpreted as the
         # number of parallel edges in the graph if the appropriate keyword
@@ -402,14 +408,14 @@ def test_from_numpy_array_parallel_edges(self):
         expected = nx.MultiDiGraph()
         expected.add_weighted_edges_from([(u, v, 1) for (u, v) in edges])
         actual = nx.from_numpy_array(A, parallel_edges=True,
-                                      create_using=nx.MultiDiGraph())
+                                     create_using=nx.MultiDiGraph())
         assert_graphs_equal(actual, expected)
         expected = nx.MultiDiGraph()
         expected.add_edges_from(set(edges), weight=1)
         # The sole self-loop (edge 0) on vertex 1 should have weight 2.
         expected[1][1][0]['weight'] = 2
         actual = nx.from_numpy_array(A, parallel_edges=False,
-                                      create_using=nx.MultiDiGraph())
+                                     create_using=nx.MultiDiGraph())
         assert_graphs_equal(actual, expected)
 
     def test_symmetric(self):
diff --git a/networkx/tests/test_convert_pandas.py b/networkx/tests/test_convert_pandas.py
--- a/networkx/tests/test_convert_pandas.py
+++ b/networkx/tests/test_convert_pandas.py
@@ -1,8 +1,8 @@
 from nose import SkipTest
-from nose.tools import assert_true
+from nose.tools import assert_true, assert_raises
 
 import networkx as nx
-from networkx.testing import assert_nodes_equal, assert_edges_equal
+from networkx.testing import assert_nodes_equal, assert_edges_equal, assert_graphs_equal
 
 
 class TestConvertPandas(object):
@@ -15,7 +15,7 @@ def setupClass(cls):
         except ImportError:
             raise SkipTest('Pandas not available.')
 
-    def __init__(self, ):
+    def __init__(self):
         global pd
         import pandas as pd
 
@@ -31,43 +31,80 @@ def __init__(self, ):
                            columns=['weight', 'cost', 0, 'b'])
         self.mdf = df.append(mdf)
 
-    def assert_equal(self, G1, G2):
-        assert_true(nx.is_isomorphic(G1, G2, edge_match=lambda x, y: x == y))
+    def test_exceptions(self):
+        G = pd.DataFrame(["a"])  # adj
+        assert_raises(nx.NetworkXError, nx.to_networkx_graph, G)
+        G = pd.DataFrame(["a", 0.0])  # elist
+        assert_raises(nx.NetworkXError, nx.to_networkx_graph, G)
+        df = pd.DataFrame([[1, 1], [1, 0]], dtype=int, index=[1, 2], columns=["a", "b"])
+        assert_raises(nx.NetworkXError, nx.from_pandas_adjacency, df)
 
-    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_edgelist(self.df, 0, 'b', True)
+        assert_graphs_equal(G, Gtrue)
+        # deprecated
         G = nx.from_pandas_dataframe(self.df, 0, 'b', True)
-        self.assert_equal(G, Gtrue)
+        assert_graphs_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())
-        self.assert_equal(MG, MGtrue)
+        MG = nx.from_pandas_edgelist(self.mdf, 0, 'b', True, nx.MultiGraph())
+        assert_graphs_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'])
-        self.assert_equal(G, Gtrue)
+        G = nx.from_pandas_edgelist(self.df, 0, 'b', ['weight', 'cost'])
+        assert_graphs_equal(G, Gtrue)
 
-    def test_from_dataframe_one_attr(self, ):
+    def test_from_edgelist_multidigraph_and_edge_attr(self):
+        # example from issue #2374
+        Gtrue = nx.MultiDiGraph([('X1', 'X4', {'Co': 'zA', 'Mi': 0, 'St': 'X1'}),
+                                 ('X1', 'X4', {'Co': 'zB', 'Mi': 54, 'St': 'X2'}),
+                                 ('X1', 'X4', {'Co': 'zB', 'Mi': 49, 'St': 'X3'}),
+                                 ('X1', 'X4', {'Co': 'zB', 'Mi': 44, 'St': 'X4'}),
+                                 ('Y1', 'Y3', {'Co': 'zC', 'Mi': 0, 'St': 'Y1'}),
+                                 ('Y1', 'Y3', {'Co': 'zC', 'Mi': 34, 'St': 'Y2'}),
+                                 ('Y1', 'Y3', {'Co': 'zC', 'Mi': 29, 'St': 'X2'}),
+                                 ('Y1', 'Y3', {'Co': 'zC', 'Mi': 24, 'St': 'Y3'}),
+                                 ('Z1', 'Z3', {'Co': 'zD', 'Mi': 0, 'St': 'Z1'}),
+                                 ('Z1', 'Z3', {'Co': 'zD', 'Mi': 14, 'St': 'X3'}),
+                                 ('Z1', 'Z3', {'Co': 'zE', 'Mi': 9, 'St': 'Z2'}),
+                                 ('Z1', 'Z3', {'Co': 'zE', 'Mi': 4, 'St': 'Z3'})])
+        df = pd.DataFrame.from_items([
+                ('O', ['X1', 'X1', 'X1', 'X1', 'Y1', 'Y1', 'Y1', 'Y1', 'Z1', 'Z1', 'Z1', 'Z1']),
+                ('D', ['X4', 'X4', 'X4', 'X4', 'Y3', 'Y3', 'Y3', 'Y3', 'Z3', 'Z3', 'Z3', 'Z3']),
+                ('St', ['X1', 'X2', 'X3', 'X4', 'Y1', 'Y2', 'X2', 'Y3', 'Z1', 'X3', 'Z2', 'Z3']),
+                ('Co', ['zA', 'zB', 'zB', 'zB', 'zC', 'zC', 'zC', 'zC', 'zD', 'zD', 'zE', 'zE']),
+                ('Mi', [0,   54,   49,   44,    0,   34,   29,   24,    0,   14,    9,   4])])
+        G1 = nx.from_pandas_edgelist(df, source='O', target='D',
+                                     edge_attr=True,
+                                     create_using=nx.MultiDiGraph())
+        G2 = nx.from_pandas_edgelist(df, source='O', target='D',
+                                     edge_attr=['St', 'Co', 'Mi'],
+                                     create_using=nx.MultiDiGraph())
+        assert_graphs_equal(G1, Gtrue)
+        assert_graphs_equal(G2, Gtrue)
+
+    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')
-        self.assert_equal(G, Gtrue)
+        G = nx.from_pandas_edgelist(self.df, 0, 'b', 'weight')
+        assert_graphs_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',)
-        self.assert_equal(G, Gtrue)
+        G = nx.from_pandas_edgelist(self.df, 0, 'b',)
+        assert_graphs_equal(G, Gtrue)
 
-    def test_from_datafram(self, ):
+    def test_from_edgelist(self):
         # Pandas DataFrame
         g = nx.cycle_graph(10)
         G = nx.Graph()
@@ -77,13 +114,34 @@ def test_from_datafram(self, ):
         source = [s for s, t, d in edgelist]
         target = [t for s, t, d in edgelist]
         weight = [d['weight'] for s, t, d in edgelist]
-        import pandas as pd
         edges = pd.DataFrame({'source': source,
                               'target': target,
                               'weight': weight})
-        GG = nx.from_pandas_dataframe(edges, edge_attr='weight')
-        assert_nodes_equal(sorted(G.nodes()), sorted(GG.nodes()))
-        assert_edges_equal(sorted(G.edges()), sorted(GG.edges()))
+        GG = nx.from_pandas_edgelist(edges, edge_attr='weight')
+        assert_nodes_equal(G.nodes(), GG.nodes())
+        assert_edges_equal(G.edges(), GG.edges())
         GW = nx.to_networkx_graph(edges, create_using=nx.Graph())
-        assert_nodes_equal(sorted(G.nodes()), sorted(GW.nodes()))
-        assert_edges_equal(sorted(G.edges()), sorted(GW.edges()))
+        assert_nodes_equal(G.nodes(), GW.nodes())
+        assert_edges_equal(G.edges(), GW.edges())
+
+    def test_from_adjacency(self):
+        nodelist = [1, 2]
+        dftrue = pd.DataFrame([[1, 1], [1, 0]], dtype=int, index=nodelist, columns=nodelist)
+        G = nx.Graph([(1, 1), (1, 2)])
+        df = nx.to_pandas_adjacency(G, dtype=int)
+        pd.testing.assert_frame_equal(df, dftrue)
+        # deprecated
+        df = nx.to_pandas_dataframe(G, dtype=int)
+        pd.testing.assert_frame_equal(df, dftrue)
+
+    def test_roundtrip(self):
+        # edgelist
+        Gtrue = nx.Graph([(1, 1), (1, 2)])
+        df = nx.to_pandas_edgelist(Gtrue)
+        G = nx.from_pandas_edgelist(df)
+        assert_graphs_equal(Gtrue, G)
+        # adjacency
+        Gtrue = nx.Graph(({1: {1: {'weight': 1}, 2: {'weight': 1}}, 2: {1: {'weight': 1}}}))
+        df = nx.to_pandas_adjacency(Gtrue, dtype=int)
+        G = nx.from_pandas_adjacency(df)
+        assert_graphs_equal(Gtrue, G)
diff --git a/networkx/tests/test_convert_scipy.py b/networkx/tests/test_convert_scipy.py
--- a/networkx/tests/test_convert_scipy.py
+++ b/networkx/tests/test_convert_scipy.py
@@ -3,7 +3,7 @@
 
 import networkx as nx
 from networkx.testing import assert_graphs_equal
-from networkx.generators.classic import barbell_graph,cycle_graph,path_graph
+from networkx.generators.classic import barbell_graph, cycle_graph, path_graph
 from networkx.testing.utils import assert_graphs_equal
 
 
@@ -15,7 +15,7 @@ def setupClass(cls):
             import numpy as np
             import scipy as sp
             import scipy.sparse as sparse
-            np_assert_equal=np.testing.assert_equal
+            np_assert_equal = np.testing.assert_equal
         except ImportError:
             raise SkipTest('SciPy sparse library not available.')
 
@@ -26,18 +26,24 @@ def __init__(self):
         self.G3 = self.create_weighted(nx.Graph())
         self.G4 = self.create_weighted(nx.DiGraph())
 
+    def test_exceptions(self):
+        class G(object):
+            format = None
+
+        assert_raises(nx.NetworkXError, nx.to_networkx_graph, G)
+
     def create_weighted(self, G):
         g = cycle_graph(4)
         e = list(g.edges())
-        source = [u for u,v in e]
-        dest = [v for u,v in e]
-        weight = [s+10 for s in source]
+        source = [u for u, v in e]
+        dest = [v for u, v in e]
+        weight = [s + 10 for s in source]
         ex = zip(source, dest, weight)
         G.add_weighted_edges_from(ex)
         return G
 
     def assert_isomorphic(self, G1, G2):
-        assert_true(nx.is_isomorphic(G1,G2))
+        assert_true(nx.is_isomorphic(G1, G2))
 
     def identity_conversion(self, G, A, create_using):
         GG = nx.from_scipy_sparse_matrix(A, create_using=create_using)
@@ -71,7 +77,7 @@ def identity_conversion(self, G, A, create_using):
 
     def test_shape(self):
         "Conversion from non-square sparse array."
-        A = sp.sparse.lil_matrix([[1,2,3],[4,5,6]])
+        A = sp.sparse.lil_matrix([[1, 2, 3], [4, 5, 6]])
         assert_raises(nx.NetworkXError, nx.from_scipy_sparse_matrix, A)
 
     def test_identity_graph_matrix(self):
@@ -105,60 +111,60 @@ def test_nodelist(self):
 
         # Make nodelist ambiguous by containing duplicates.
         nodelist += [nodelist[0]]
-        assert_raises(nx.NetworkXError, nx.to_numpy_matrix, P3, 
+        assert_raises(nx.NetworkXError, nx.to_numpy_matrix, P3,
                       nodelist=nodelist)
 
     def test_weight_keyword(self):
         WP4 = nx.Graph()
-        WP4.add_edges_from( (n,n+1,dict(weight=0.5,other=0.3)) 
-                            for n in range(3) )
+        WP4.add_edges_from((n, n + 1, dict(weight=0.5, other=0.3))
+                           for n in range(3))
         P4 = path_graph(4)
         A = nx.to_scipy_sparse_matrix(P4)
         np_assert_equal(A.todense(),
-                        nx.to_scipy_sparse_matrix(WP4,weight=None).todense())
-        np_assert_equal(0.5*A.todense(),
+                        nx.to_scipy_sparse_matrix(WP4, weight=None).todense())
+        np_assert_equal(0.5 * A.todense(),
                         nx.to_scipy_sparse_matrix(WP4).todense())
-        np_assert_equal(0.3*A.todense(),
-                        nx.to_scipy_sparse_matrix(WP4,weight='other').todense())
+        np_assert_equal(0.3 * A.todense(),
+                        nx.to_scipy_sparse_matrix(WP4, weight='other').todense())
 
     def test_format_keyword(self):
         WP4 = nx.Graph()
-        WP4.add_edges_from( (n,n+1,dict(weight=0.5,other=0.3))
-                            for n in range(3) )
+        WP4.add_edges_from((n, n + 1, dict(weight=0.5, other=0.3))
+                           for n in range(3))
         P4 = path_graph(4)
         A = nx.to_scipy_sparse_matrix(P4, format='csr')
         np_assert_equal(A.todense(),
-                        nx.to_scipy_sparse_matrix(WP4,weight=None).todense())
+                        nx.to_scipy_sparse_matrix(WP4, weight=None).todense())
 
         A = nx.to_scipy_sparse_matrix(P4, format='csc')
         np_assert_equal(A.todense(),
-                        nx.to_scipy_sparse_matrix(WP4,weight=None).todense())
+                        nx.to_scipy_sparse_matrix(WP4, weight=None).todense())
 
         A = nx.to_scipy_sparse_matrix(P4, format='coo')
         np_assert_equal(A.todense(),
-                        nx.to_scipy_sparse_matrix(WP4,weight=None).todense())
+                        nx.to_scipy_sparse_matrix(WP4, weight=None).todense())
 
         A = nx.to_scipy_sparse_matrix(P4, format='bsr')
         np_assert_equal(A.todense(),
-                        nx.to_scipy_sparse_matrix(WP4,weight=None).todense())
+                        nx.to_scipy_sparse_matrix(WP4, weight=None).todense())
 
         A = nx.to_scipy_sparse_matrix(P4, format='lil')
         np_assert_equal(A.todense(),
-                        nx.to_scipy_sparse_matrix(WP4,weight=None).todense())
+                        nx.to_scipy_sparse_matrix(WP4, weight=None).todense())
 
         A = nx.to_scipy_sparse_matrix(P4, format='dia')
         np_assert_equal(A.todense(),
-                        nx.to_scipy_sparse_matrix(WP4,weight=None).todense())
+                        nx.to_scipy_sparse_matrix(WP4, weight=None).todense())
 
         A = nx.to_scipy_sparse_matrix(P4, format='dok')
         np_assert_equal(A.todense(),
-                        nx.to_scipy_sparse_matrix(WP4,weight=None).todense())
+                        nx.to_scipy_sparse_matrix(WP4, weight=None).todense())
 
     @raises(nx.NetworkXError)
     def test_format_keyword_raise(self):
         WP4 = nx.Graph()
-        WP4.add_edges_from( (n,n+1,dict(weight=0.5,other=0.3))
-                            for n in range(3) )
+        WP4.add_edges_from((n, n + 1, dict(weight=0.5, other=0.3))
+                           for n in range(3))
         P4 = path_graph(4)
         nx.to_scipy_sparse_matrix(P4, format='any_other')
 
@@ -174,19 +180,19 @@ def test_empty(self):
 
     def test_ordering(self):
         G = nx.DiGraph()
-        G.add_edge(1,2)
-        G.add_edge(2,3)
-        G.add_edge(3,1)
-        M = nx.to_scipy_sparse_matrix(G,nodelist=[3,2,1])
-        np_assert_equal(M.todense(), np.matrix([[0,0,1],[1,0,0],[0,1,0]]))
+        G.add_edge(1, 2)
+        G.add_edge(2, 3)
+        G.add_edge(3, 1)
+        M = nx.to_scipy_sparse_matrix(G, nodelist=[3, 2, 1])
+        np_assert_equal(M.todense(), np.matrix([[0, 0, 1], [1, 0, 0], [0, 1, 0]]))
 
     def test_selfloop_graph(self):
-        G = nx.Graph([(1,1)])
+        G = nx.Graph([(1, 1)])
         M = nx.to_scipy_sparse_matrix(G)
         np_assert_equal(M.todense(), np.matrix([[1]]))
 
     def test_selfloop_digraph(self):
-        G = nx.DiGraph([(1,1)])
+        G = nx.DiGraph([(1, 1)])
         M = nx.to_scipy_sparse_matrix(G)
         np_assert_equal(M.todense(), np.matrix([[1]]))