code: def from_pandas_edgelist(
      df,
      source="source",
      target="target",
      edge_attr=None,
      create_using=None,
      edge_key=None,
  ):
      """Returns a graph from Pandas DataFrame containing an edge list.
  
      The Pandas DataFrame should contain at least two columns of node names and
      zero or more columns of edge attributes. Each row will be processed as one
      edge instance.
  
      Note: This function iterates over DataFrame.values, which is not
      guaranteed to retain the data type across columns in the row. This is only
      a problem if your row is entirely numeric and a mix of ints and floats. In
      that case, all values will be returned as floats. See the
      DataFrame.iterrows documentation for an example.
  
      Parameters
      ----------
      df : Pandas DataFrame
          An edge list representation of a graph
  
      source : str or int
          A valid column name (string or integer) for the source nodes (for the
          directed case).
  
      target : str or int
          A valid column name (string or integer) for the target nodes (for the
          directed case).
  
      edge_attr : str or int, iterable, True, or None
          A valid column name (str or int) or iterable of column names that are
          used to retrieve items and add them to the graph as edge attributes.
          If `True`, all of the remaining columns will be added.
          If `None`, no edge attributes are added to the graph.
  
      create_using : NetworkX graph constructor, optional (default=nx.Graph)
          Graph type to create. If graph instance, then cleared before populated.
  
      edge_key : str or None, optional (default=None)
          A valid column name for the edge keys (for a MultiGraph). The values in
          this column are used for the edge keys when adding edges if create_using
          is a multigraph.
  
      If you have node attributes stored in a separate dataframe `df_nodes`,
      you can load those attributes to the graph `G` using the following code:
  
      ```
      df_nodes = pd.DataFrame({"node_id": [1, 2, 3], "attribute1": ["A", "B", "C"]})
      G.add_nodes_from((n, dict(d)) for n, d in df_nodes.iterrows())
      ```
  
      See Also
      --------
      to_pandas_edgelist
  
      Examples
      --------
      Simple integer weights on edges:
  
      >>> import pandas as pd
      >>> pd.options.display.max_columns = 20
      >>> import numpy as np
      >>> rng = np.random.RandomState(seed=5)
      >>> ints = rng.randint(1, 11, size=(3, 2))
      >>> a = ["A", "B", "C"]
      >>> b = ["D", "A", "E"]
      >>> df = pd.DataFrame(ints, columns=["weight", "cost"])
      >>> df[0] = a
      >>> df["b"] = b
      >>> df[["weight", "cost", 0, "b"]]
         weight  cost  0  b
      0       4     7  A  D
      1       7     1  B  A
      2      10     9  C  E
      >>> G = nx.from_pandas_edgelist(df, 0, "b", ["weight", "cost"])
      >>> G["E"]["C"]["weight"]
      10
      >>> G["E"]["C"]["cost"]
      9
      >>> edges = pd.DataFrame(
      ...     {
      ...         "source": [0, 1, 2],
      ...         "target": [2, 2, 3],
      ...         "weight": [3, 4, 5],
      ...         "color": ["red", "blue", "blue"],
      ...     }
      ... )
      >>> G = nx.from_pandas_edgelist(edges, edge_attr=True)
      >>> G[0][2]["color"]
      'red'
  
      Build multigraph with custom keys:
  
      >>> edges = pd.DataFrame(
      ...     {
      ...         "source": [0, 1, 2, 0],
      ...         "target": [2, 2, 3, 2],
      ...         "my_edge_key": ["A", "B", "C", "D"],
      ...         "weight": [3, 4, 5, 6],
      ...         "color": ["red", "blue", "blue", "blue"],
      ...     }
      ... )
      >>> G = nx.from_pandas_edgelist(
      ...     edges,
      ...     edge_key="my_edge_key",
      ...     edge_attr=["weight", "color"],
      ...     create_using=nx.MultiGraph(),
      ... )
      >>> G[0][2]
      AtlasView({'A': {'weight': 3, 'color': 'red'}, 'D': {'weight': 6, 'color': 'blue'}})
  
  
      """
      g = nx.empty_graph(0, create_using)
  
      if edge_attr is None:
          g.add_edges_from(zip(df[source], df[target]))
          return g
  
      reserved_columns = [source, target]
  
      # Additional columns requested
      attr_col_headings = []
      attribute_data = []
      if edge_attr is True:
          attr_col_headings = [
              c for c in df.columns if c not in reserved_columns
          ]
      elif isinstance(edge_attr, list | tuple):
          attr_col_headings = edge_attr
      else:
          attr_col_headings = [edge_attr]
      if len(attr_col_headings) == 0:
          raise nx.NetworkXError(
              f"Invalid edge_attr argument: No columns found with name: {attr_col_headings}"
          )
  
      try:
          attribute_data = zip(*[df[col] for col in attr_col_headings])
      except (KeyError, TypeError) as err:
          msg = f"Invalid edge_attr argument: {edge_attr}"
          raise nx.NetworkXError(msg) from err
  
      if g.is_multigraph():
          # => append the edge keys from the df to the bundled data
          if edge_key is not None:
              try:
                  multigraph_edge_keys = df[edge_key]
                  attribute_data = zip(
                      attribute_data, multigraph_edge_keys
                  )
              except (KeyError, TypeError) as err:
                  msg = f"Invalid edge_key argument: {edge_key}"
                  raise nx.NetworkXError(msg) from err
  
          for s, t, attrs in zip(
              df[source], df[target], attribute_data
          ):
              if edge_key is not None:
                  attrs, multigraph_edge_key = attrs
                  key = g.add_edge(s, t, key=multigraph_edge_key)
              else:
                  key = g.add_edge(s, t)
  
              g[s][t][key].update(zip(attr_col_headings, attrs))
      else:
          for s, t, attrs in zip(
              df[source], df[target], attribute_data
          ):
              g.add_edge(s, t)
              g[s][t].update(zip(attr_col_headings, attrs))
  
      return g
  
file_path: networkx/networkx/convert_matrix.py
imports: import itertools
  from collections import defaultdict
  import networkx
  from networkx.utils import not_implemented_for
label_desc: Use image node_id 4 for calling a global function with example usage: from_pandas_edgelist(df, source, target, edge_attr, create_using, edge_key) and returns: g, g