class_docstr: :class:`AbstractSampler` is a abstract class, all sampler should inherit from it. This sampler supports returning
  a certain number of random value_ids according to the input key_id, and it also supports to prohibit
  certain key-value pairs by setting used_ids.
  
  Args:
      distribution (str): The string of distribution, which is used for subclass.
  
  Attributes:
      used_ids (numpy.ndarray): The result of :meth:`get_used_ids`.
class_docstr_tok: [":","class",":","`","AbstractSampler","`","is","a","abstract","class",",","all","sampler","should","inherit","from","it",".","This","sampler","supports","returning","a","certain","number","of","random","value_ids","according","to","the","input","key_id",",","and","it","also","supports","to","prohibit","certain","key-value","pairs","by","setting","used_ids",".","Args",":","distribution","(","str",")",":","The","string","of","distribution",",","which","is","used","for","subclass",".","Attributes",":","used_ids","(","numpy.ndarray",")",":","The","result","of",":","meth",":","`","get_used_ids","`","."]
docstr: Sampling by key_ids.
  
  Args:
      key_ids (numpy.ndarray or list): Input key_ids.
      num (int): Number of sampled value_ids for each key_id.
  
  Returns:
      torch.tensor: Sampled value_ids.
      value_ids[0], value_ids[len(key_ids)], value_ids[len(key_ids) * 2], ..., value_id[len(key_ids) * (num - 1)]
      is sampled for key_ids[0];
      value_ids[1], value_ids[len(key_ids) + 1], value_ids[len(key_ids) * 2 + 1], ...,
      value_id[len(key_ids) * (num - 1) + 1] is sampled for key_ids[1]; ...; and so on.
docstr_tok: ["Sampling","by","key_ids",".","Args",":","key_ids","(","numpy.ndarray","or","list",")",":","Input","key_ids",".","num","(","int",")",":","Number","of","sampled","value_ids","for","each","key_id",".","Returns",":","torch.tensor",":","Sampled","value_ids",".","value_ids","[","0","]",",","value_ids","[","len","(","key_ids",")","]",",","value_ids","[","len","(","key_ids",")","*","2","]",",","...",",","value_id","[","len","(","key_ids",")","*","(","num","-","1",")","]","is","sampled","for","key_ids","[","0","]",";","value_ids","[","1","]",",","value_ids","[","len","(","key_ids",")","+","1","]",",","value_ids","[","len","(","key_ids",")","*","2","+","1","]",",","...",",","value_id","[","len","(","key_ids",")","*","(","num","-","1",")","+","1","]","is","sampled","for","key_ids","[","1","]",";","...",";","and","so","on","."]
code: def sample_by_key_ids(self, key_ids, num):
      """Sampling by key_ids.
  
      Args:
          key_ids (numpy.ndarray or list): Input key_ids.
          num (int): Number of sampled value_ids for each key_id.
  
      Returns:
          torch.tensor: Sampled value_ids.
          value_ids[0], value_ids[len(key_ids)], value_ids[len(key_ids) * 2], ..., value_id[len(key_ids) * (num - 1)]
          is sampled for key_ids[0];
          value_ids[1], value_ids[len(key_ids) + 1], value_ids[len(key_ids) * 2 + 1], ...,
          value_id[len(key_ids) * (num - 1) + 1] is sampled for key_ids[1]; ...; and so on.
      """
      key_ids = np.array(key_ids)
      key_num = len(key_ids)
      total_num = key_num * num
      if (key_ids == key_ids[0]).all():
          key_id = key_ids[0]
          used = np.array(list(self.used_ids[key_id]))
          value_ids = self.sampling(total_num)
          check_list = np.arange(total_num)[np.isin(value_ids, used)]
          while len(check_list) > 0:
              value_ids[check_list] = value = self.sampling(
                  len(check_list)
              )
              mask = np.isin(value, used)
              check_list = check_list[mask]
      else:
          value_ids = np.zeros(total_num, dtype=np.int64)
          check_list = np.arange(total_num)
          key_ids = np.tile(key_ids, num)
          while len(check_list) > 0:
              value_ids[check_list] = self.sampling(len(check_list))
              check_list = np.array(
                  [
                      i
                      for i, used, v in zip(
                          check_list,
                          self.used_ids[key_ids[check_list]],
                          value_ids[check_list],
                      )
                      if v in used
                  ]
              )
      return torch.tensor(value_ids, dtype=torch.long)
  
imports: import copy
  import numpy
  from numpy.random import sample
  import torch
  from collections import Counter
label_desc: Use image node_id 9 for calling the AbstractSampler obj's underlying member method code with example usage: obj.sample_by_key_ids(key_ids, num) and returns: torch