class_docstr: Duck-typed version of PyG's GraphStore and FeatureStore.
class_docstr_tok: ["Duck-typed","version","of","PyG","'s","GraphStore","and","FeatureStore","."]
docstr: Given a cudf (NOT dask_cudf) DataFrame of sampling results and a dictionary
  of non-renumbered vertex ids grouped by vertex type, this method
  outputs two dictionaries:
      1. row_dict
      2. col_dict
  (1) row_dict corresponds to the renumbered source vertex ids grouped
      by PyG edge type - (src, type, dst) tuple.
  (2) col_dict corresponds to the renumbered destination vertex ids grouped
      by PyG edge type (src, type, dst) tuple.
  * The two outputs combined make a PyG "edge index".
  * The ith element of each array corresponds to the same edge.
  * The _get_vertex_groups_from_sample() method is usually called
    before this one to get the noi_index.
  
  Example Input: Series({
          'majors': [0, 5, 11, 3],
          'minors': [8, 2, 3, 5]},
          'edge_type': [1, 3, 5, 14]
      }),
      {
          'blue_vertex': [0, 5],
          'red_vertex': [3, 11],
          'green_vertex': [2, 8]
      }
  Output: {
          ('blue', 'etype1', 'green'): [0, 1],
          ('red', 'etype2', 'red'): [1],
          ('red', 'etype3', 'blue'): [0]
      },
      {
          ('blue', 'etype1', 'green'): [1, 0],
          ('red', 'etype2', 'red'): [0],
          ('red', 'etype3', 'blue'): [1]
      }
docstr_tok: ["Given","a","cudf","(","NOT","dask_cudf",")","DataFrame","of","sampling","results","and","a","dictionary","of","non-renumbered","vertex","ids","grouped","by","vertex","type",",","this","method","outputs","two","dictionaries",":","1.","row_dict","2.","col_dict","(","1",")","row_dict","corresponds","to","the","renumbered","source","vertex","ids","grouped","by","PyG","edge","type","-","(","src",",","type",",","dst",")","tuple",".","(","2",")","col_dict","corresponds","to","the","renumbered","destination","vertex","ids","grouped","by","PyG","edge","type","(","src",",","type",",","dst",")","tuple",".","*","The","two","outputs","combined","make","a","PyG","``","edge","index","''",".","*","The","ith","element","of","each","array","corresponds","to","the","same","edge",".","*","The","_get_vertex_groups_from_sample","(",")","method","is","usually","called","before","this","one","to","get","the","noi_index",".","Example","Input",":","Series","(","{","'majors","'",":","[","0",",","5",",","11",",","3","]",",","'minors","'",":","[","8",",","2",",","3",",","5","]","}",",","'edge_type","'",":","[","1",",","3",",","5",",","14","]","}",")",",","{","'blue_vertex","'",":","[","0",",","5","]",",","'red_vertex","'",":","[","3",",","11","]",",","'green_vertex","'",":","[","2",",","8","]","}","Output",":","{","(","'blue","'",",","'etype1","'",",","'green","'",")",":","[","0",",","1","]",",","(","'red","'",",","'etype2","'",",","'red","'",")",":","[","1","]",",","(","'red","'",",","'etype3","'",",","'blue","'",")",":","[","0","]","}",",","{","(","'blue","'",",","'etype1","'",",","'green","'",")",":","[","1",",","0","]",",","(","'red","'",",","'etype2","'",",","'red","'",")",":","[","0","]",",","(","'red","'",",","'etype3","'",",","'blue","'",")",":","[","1","]","}"]
code: def _get_renumbered_edge_groups_from_sample(
      self, sampling_results: cudf.DataFrame, noi_index: dict
  ) -> Tuple[
      Dict[Tuple[str, str, str], torch.Tensor],
      Tuple[Dict[Tuple[str, str, str], torch.Tensor]],
  ]:
      """
      Given a cudf (NOT dask_cudf) DataFrame of sampling results and a dictionary
      of non-renumbered vertex ids grouped by vertex type, this method
      outputs two dictionaries:
          1. row_dict
          2. col_dict
      (1) row_dict corresponds to the renumbered source vertex ids grouped
          by PyG edge type - (src, type, dst) tuple.
      (2) col_dict corresponds to the renumbered destination vertex ids grouped
          by PyG edge type (src, type, dst) tuple.
      * The two outputs combined make a PyG "edge index".
      * The ith element of each array corresponds to the same edge.
      * The _get_vertex_groups_from_sample() method is usually called
        before this one to get the noi_index.
  
      Example Input: Series({
              'majors': [0, 5, 11, 3],
              'minors': [8, 2, 3, 5]},
              'edge_type': [1, 3, 5, 14]
          }),
          {
              'blue_vertex': [0, 5],
              'red_vertex': [3, 11],
              'green_vertex': [2, 8]
          }
      Output: {
              ('blue', 'etype1', 'green'): [0, 1],
              ('red', 'etype2', 'red'): [1],
              ('red', 'etype3', 'blue'): [0]
          },
          {
              ('blue', 'etype1', 'green'): [1, 0],
              ('red', 'etype2', 'red'): [0],
              ('red', 'etype3', 'blue'): [1]
          }
  
      """
      row_dict = {}
      col_dict = {}
      # If there is only 1 edge type (includes heterogeneous graphs)
      if len(self.edge_types) == 1:
          t_pyg_type = list(self.__edge_types_to_attrs.values())[
              0
          ].edge_type
          src_type, _, dst_type = t_pyg_type
  
          # If there is only 1 node type (homogeneous)
          # This should only occur if the cuGraph loader was
          # not used.  This logic is deprecated.
          if len(self.node_types) == 1:
              warnings.warn(
                  "Renumbering after sampling for homogeneous graphs is deprecated.",
                  FutureWarning,
              )
  
              # Create a dataframe mapping old ids to new ids.
              vtype = src_type
              id_table = noi_index[vtype]
              id_map = cudf.Series(
                  cupy.arange(id_table.shape[0], dtype="int32"),
                  name="new_id",
                  index=cupy.asarray(id_table),
              ).sort_index()
  
              # Renumber the majors using binary search
              # Step 1: get the index of the new id
              ix_r = torch.searchsorted(
                  torch.as_tensor(id_map.index.values, device="cuda"),
                  torch.as_tensor(
                      sampling_results.majors.values, device="cuda"
                  ),
              )
              # Step 2: Go from id indices to actual ids
              row_dict[t_pyg_type] = torch.as_tensor(
                  id_map.values, device="cuda"
              )[ix_r]
  
              # Renumber the minors using binary search
              # Step 1: get the index of the new id
              ix_c = torch.searchsorted(
                  torch.as_tensor(id_map.index.values, device="cuda"),
                  torch.as_tensor(
                      sampling_results.minors.values, device="cuda"
                  ),
              )
              # Step 2: Go from id indices to actual ids
              col_dict[t_pyg_type] = torch.as_tensor(
                  id_map.values, device="cuda"
              )[ix_c]
          else:
              # Handle the heterogeneous case where there is only 1 edge type
              dst_id_table = noi_index[dst_type]
              dst_id_map = cudf.DataFrame(
                  {
                      "dst": cupy.asarray(dst_id_table),
                      "new_id": cupy.arange(dst_id_table.shape[0]),
                  }
              ).set_index("dst")
              dst = dst_id_map["new_id"].loc[sampling_results.minors]
              col_dict[t_pyg_type] = torch.as_tensor(
                  dst.values, device="cuda"
              )
  
              src_id_table = noi_index[src_type]
              src_id_map = cudf.DataFrame(
                  {
                      "src": cupy.asarray(src_id_table),
                      "new_id": cupy.arange(src_id_table.shape[0]),
                  }
              ).set_index("src")
              src = src_id_map["new_id"].loc[sampling_results.majors]
              row_dict[t_pyg_type] = torch.as_tensor(
                  src.values, device="cuda"
              )
  
      else:
          # This will retrieve the single string representation.
          # It needs to be converted to a tuple in the for loop below.
          eoi_types = (
              cudf.Series(self.__edge_type_offsets["type"])
              .iloc[sampling_results.edge_type.astype("int32")]
              .reset_index(drop=True)
          )
  
          eoi_types = (
              cudf.Series(eoi_types, name="t").groupby("t").groups
          )
  
          for pyg_can_edge_type_str, ix in eoi_types.items():
              pyg_can_edge_type = tuple(
                  pyg_can_edge_type_str.split("__")
              )
  
              if self.__order == "CSR":
                  src_type, _, dst_type = pyg_can_edge_type
              else:  # CSC
                  dst_type, _, src_type = pyg_can_edge_type
  
              # Get the de-offsetted minors
              dst_num_type = self._numeric_vertex_type_from_name(
                  dst_type
              )
              minors = torch.as_tensor(
                  sampling_results.minors.iloc[ix].values, device="cuda"
              )
              minors -= self.__vertex_type_offsets["start"][
                  dst_num_type
              ]
  
              # Create the col entry for this type
              dst_id_table = noi_index[dst_type]
              dst_id_map = (
                  cudf.Series(cupy.asarray(dst_id_table), name="dst")
                  .reset_index()
                  .rename(columns={"index": "new_id"})
                  .set_index("dst")
              )
              dst = dst_id_map["new_id"].loc[cupy.asarray(minors)]
              col_dict[pyg_can_edge_type] = torch.as_tensor(
                  dst.values, device="cuda"
              )
  
              # Get the de-offsetted majors
              src_num_type = self._numeric_vertex_type_from_name(
                  src_type
              )
              majors = torch.as_tensor(
                  sampling_results.majors.iloc[ix].values, device="cuda"
              )
              majors -= self.__vertex_type_offsets["start"][
                  src_num_type
              ]
  
              # Create the row entry for this type
              src_id_table = noi_index[src_type]
              src_id_map = (
                  cudf.Series(cupy.asarray(src_id_table), name="src")
                  .reset_index()
                  .rename(columns={"index": "new_id"})
                  .set_index("src")
              )
              src = src_id_map["new_id"].loc[cupy.asarray(majors)]
              row_dict[pyg_can_edge_type] = torch.as_tensor(
                  src.values, device="cuda"
              )
  
      return row_dict, col_dict
  
imports: from typing import Optional, Tuple, Any, Union, List, Dict
  from enum import Enum, auto
  from dataclasses import dataclass
  from collections import defaultdict
  from itertools import chain
  from functools import cached_property
  import numpy
  import cupy
  import pandas
  import cudf
  import cugraph
  import warnings
  import dask.array
  import dask.dataframe
  import dask.distributed
  import dask_cudf
  from cugraph.utilities.utils import import_optional, MissingModule
label_desc: Use image node_id 23 for calling the CuGraphStore obj's underlying member method code with example usage: obj._get_renumbered_edge_groups_from_sample(sampling_results, noi_index) and returns: row_dict,  col_dict