class_docstr: Median Stopping-Rule similar to Golovin et al.
  "Google Vizier: A Service for Black-Box Optimization".
  
  * For a Trial `t`, the best objective value is found.
  * Then the best objective value for every other trial is found.
  * Finally, the best-objective for the trial is compared to the median of
    the best-objectives of all other trials.
  
  If trial `t`'s best objective is worse than that median, it is
  stopped.
  
  If `t` has not reached the minimum iterations or there are not
  yet the requested number of comparison trials, `t` is not
  stopped. If `t` is all nan's it is stopped by default.
  
  Args:
      min_iterations (int): the minimum number of iterations a trial runs for
          before it is considered for stopping.
      min_trials (int): the minimum number of comparison trials needed for a
          trial to be stopped.
class_docstr_tok: ["Median","Stopping-Rule","similar","to","Golovin","et","al",".","``","Google","Vizier",":","A","Service","for","Black-Box","Optimization","''",".","*","For","a","Trial","`","t","`",",","the","best","objective","value","is","found",".","*","Then","the","best","objective","value","for","every","other","trial","is","found",".","*","Finally",",","the","best-objective","for","the","trial","is","compared","to","the","median","of","the","best-objectives","of","all","other","trials",".","If","trial","`","t","`","'s","best","objective","is","worse","than","that","median",",","it","is","stopped",".","If","`","t","`","has","not","reached","the","minimum","iterations","or","there","are","not","yet","the","requested","number","of","comparison","trials",",","`","t","`","is","not","stopped",".","If","`","t","`","is","all","nan","'s","it","is","stopped","by","default",".","Args",":","min_iterations","(","int",")",":","the","minimum","number","of","iterations","a","trial","runs","for","before","it","is","considered","for","stopping",".","min_trials","(","int",")",":","the","minimum","number","of","comparison","trials","needed","for","a","trial","to","be","stopped","."]
docstr: Args:
      trial (sherpa.Trial): trial to be stopped.
      results (pandas.DataFrame): all results so far.
      lower_is_better (bool): whether lower objective values are better.
  
  Returns:
      bool: decision.
docstr_tok: ["Args",":","trial","(","sherpa.Trial",")",":","trial","to","be","stopped",".","results","(","pandas.DataFrame",")",":","all","results","so","far",".","lower_is_better","(","bool",")",":","whether","lower","objective","values","are","better",".","Returns",":","bool",":","decision","."]
code: def should_trial_stop(self, trial, results, lower_is_better):
      """
      Args:
          trial (sherpa.Trial): trial to be stopped.
          results (pandas.DataFrame): all results so far.
          lower_is_better (bool): whether lower objective values are better.
  
      Returns:
          bool: decision.
      """
      if len(results) == 0:
          return False
  
      trial_rows = results.loc[results["Trial-ID"] == trial.id]
  
      max_iteration = trial_rows["Iteration"].max()
      if max_iteration < self.min_iterations:
          return False
  
      trial_obj_val = (
          trial_rows["Objective"].min()
          if lower_is_better
          else trial_rows["Objective"].max()
      )
  
      if numpy.isnan(trial_obj_val) and not trial_rows.empty:
          alglogger.debug(
              "Value {} is NaN: {}, trial rows: {}".format(
                  trial_obj_val, numpy.isnan(trial_obj_val), trial_rows
              )
          )
          return True
  
      other_trial_ids = set(results["Trial-ID"]) - {trial.id}
      comparison_vals = []
  
      for tid in other_trial_ids:
          trial_rows = results.loc[results["Trial-ID"] == tid]
  
          max_iteration = trial_rows["Iteration"].max()
          if max_iteration < self.min_iterations:
              continue
  
          valid_rows = trial_rows.loc[
              trial_rows["Iteration"] <= max_iteration
          ]
          obj_val = (
              valid_rows["Objective"].min()
              if lower_is_better
              else valid_rows["Objective"].max()
          )
          comparison_vals.append(obj_val)
  
      if len(comparison_vals) < self.min_trials:
          return False
  
      if lower_is_better:
          decision = trial_obj_val > numpy.nanmedian(comparison_vals)
      else:
          decision = trial_obj_val < numpy.nanmedian(comparison_vals)
  
      return decision
  
imports: import os
  import random
  import numpy
  import logging
  import sherpa
  import pandas
  import sklearn.gaussian_process
  from sherpa.core import Choice, Continuous, Discrete, Ordinal, AlgorithmState
  from sherpa.core import rng
  import sklearn.model_selection
  import collections
label_desc: Use image node_id 2 for calling the MedianStoppingRule obj's underlying member method code with example usage: obj.should_trial_stop(trial, results, lower_is_better) and returns: decision, False, False, True, False