class_docstr: Class for generating datasets from ImageNet superclasses.
class_docstr_tok: ["Class","for","generating","datasets","from","ImageNet","superclasses","."]
docstr: Split superclass into two disjoint sets of subclasses.
  
  Args:
      superclass_wnid (str): WordNet ID of superclass node
      Nsubclasses (int): Number of subclasses per superclass
                         (not used when balanced is True)
      balanced (bool): Whether or not the dataset should be
                       balanced over superclasses
      split_type ("good"/"bad"/"rand"): Whether the subclass
                       partitioning should be more or less 
                       adversarial or random
      rng (RandomState): Random number generator
  
  Returns:
      class_ranges (tuple): Tuple of lists of subclasses
docstr_tok: ["Split","superclass","into","two","disjoint","sets","of","subclasses",".","Args",":","superclass_wnid","(","str",")",":","WordNet","ID","of","superclass","node","Nsubclasses","(","int",")",":","Number","of","subclasses","per","superclass","(","not","used","when","balanced","is","True",")","balanced","(","bool",")",":","Whether","or","not","the","dataset","should","be","balanced","over","superclasses","split_type","(","``","good","''","\/","''","bad","''","\/","''","rand","''",")",":","Whether","the","subclass","partitioning","should","be","more","or","less","adversarial","or","random","rng","(","RandomState",")",":","Random","number","generator","Returns",":","class_ranges","(","tuple",")",":","Tuple","of","lists","of","subclasses"]
code: def split_superclass(
      self,
      superclass_wnid,
      Nsubclasses,
      balanced,
      split_type,
      rng=np.random.RandomState(2),
  ):
      """
      Split superclass into two disjoint sets of subclasses.
  
      Args:
          superclass_wnid (str): WordNet ID of superclass node
          Nsubclasses (int): Number of subclasses per superclass
                             (not used when balanced is True)
          balanced (bool): Whether or not the dataset should be
                           balanced over superclasses
          split_type ("good"/"bad"/"rand"): Whether the subclass
                           partitioning should be more or less
                           adversarial or random
          rng (RandomState): Random number generator
  
      Returns:
          class_ranges (tuple): Tuple of lists of subclasses
      """
  
      # Find a descendant of the superclass that has at least two children
      G = self.hierarchy.graph
      node, desc = superclass_wnid, sorted(
          list(G.successors(superclass_wnid))
      )
      while len(desc) == 1:
          node = desc[0]
          desc = sorted(list(G.successors(node)))
  
      # Map each descendant to its ImageNet subclasses
      desc_map = {}
      for d in desc:
          desc_map[d] = sorted(list(self.hierarchy.leaves_reachable(d)))
  
      # Map sorted by nodes that have the maximum number of children
      desc_sorted = sorted(desc_map.items(), key=lambda x: -len(x[1]))
  
      # If not balanced, we will pick as many subclasses as possible
      # from this superclass (ignoring Nsubclasses)
      assert Nsubclasses >= 2
      if not balanced:
          S = sum([len(d) for d in desc_map.values()])
          assert S >= Nsubclasses
          Nsubclasses = S
          if Nsubclasses % 2 != 0:
              Nsubclasses -= 1
  
      # Split superclasses into two disjoint sets
      assert Nsubclasses % 2 == 0
      Nh = Nsubclasses // 2
  
      if split_type == "rand":
          # If split is random, aggregate all subclasses, subsample
          # the desired number, and then partition into two
          desc_node_list = []
          for d in desc_map.values():
              desc_node_list.extend(d)
          sel = rng.choice(
              sorted(desc_node_list), Nh * 2, replace=False
          )
          split = (sel[:Nh], sel[Nh:])
      else:
          # If split is good, we will partition similar subclasses across
          # both domains. If it is bad, similar subclasses will feature in
          # one or the other
  
          split, spare = ([], []), []
  
          for k, v in desc_sorted:
              l = [len(s) for s in split]
              if split_type == "bad":
                  if l[0] <= l[1] and l[0] < Nh:
                      if len(v) > Nh - l[0]:
                          spare.extend(v[Nh - l[0] :])
                      split[0].extend(v[: Nh - l[0]])
                  elif l[1] < Nh:
                      if len(v) > Nh - l[1]:
                          spare.extend(v[Nh - l[1] :])
                      split[1].extend(v[: Nh - l[1]])
              else:
                  if len(v) == 1:
                      i1 = 1 if l[0] < Nh else 0
                  else:
                      i1 = min(len(v) // 2, Nh - l[0])
  
                  if l[0] < Nh:
                      split[0].extend(v[:i1])
                  if l[1] < Nh:
                      split[1].extend(v[i1 : i1 + Nh - l[1]])
  
          if split_type == "bad":
              l = [len(s) + 0 for s in split]
              assert max(l) == Nh
              if l[0] < Nh:
                  split[0].extend(spare[: Nh - l[0]])
              if l[1] < Nh:
                  split[1].extend(spare[: Nh - l[1]])
  
      assert len(split[0]) == len(split[1]) and not set(
          split[0]
      ).intersection(split[1])
      class_ranges = (
          [self.hierarchy.LEAF_ID_TO_NUM[s] for s in split[0]],
          [self.hierarchy.LEAF_ID_TO_NUM[s] for s in split[1]],
      )
  
      return class_ranges
  
imports: import sys, os
  import json
  import numpy
  import pandas
  import urllib
  from collections import OrderedDict, Counter
  import operator
  import networkx
  from ..datasets import DATASETS
label_desc: Use image node_id 2 for calling the BreedsDatasetGenerator obj's underlying member method code with example usage: obj.split_superclass(superclass_wnid, Nsubclasses, balanced, split_type, rng) and returns: class_ranges