class_docstr: Tests for multiple comparisons
  
  Parameters
  ----------
  data : ndarray
      independent data samples
  groups : ndarray
      group labels corresponding to each data point
  group_order : list[str], optional
      the desired order for the group mean results to be reported in. If
      not specified, results are reported in increasing order.
      If group_order does not contain all labels that are in groups, then
      only those observations are kept that have a label in group_order.
class_docstr_tok: ["Tests","for","multiple","comparisons","Parameters","--","--","--","--","--","data",":","ndarray","independent","data","samples","groups",":","ndarray","group","labels","corresponding","to","each","data","point","group_order",":","list","[","str","]",",","optional","the","desired","order","for","the","group","mean","results","to","be","reported","in",".","If","not","specified",",","results","are","reported","in","increasing","order",".","If","group_order","does","not","contain","all","labels","that","are","in","groups",",","then","only","those","observations","are","kept","that","have","a","label","in","group_order","."]
code: def __init__(self, data, groups, group_order=None):
      if len(data) != len(groups):
          raise ValueError(
              "data has %d elements and groups has %d"
              % (len(data), len(groups))
          )
      self.data = np.asarray(data)
      self.groups = groups = np.asarray(groups)
  
      # Allow for user-provided sorting of groups
      if group_order is None:
          self.groupsunique, self.groupintlab = np.unique(
              groups, return_inverse=True
          )
      else:
          # check if group_order has any names not in groups
          for grp in group_order:
              if grp not in groups:
                  raise ValueError(
                      "group_order value '%s' not found in groups" % grp
                  )
          self.groupsunique = np.array(group_order)
          self.groupintlab = np.empty(len(data), int)
          self.groupintlab.fill(-999)  # instead of a nan
          count = 0
          for name in self.groupsunique:
              idx = np.where(self.groups == name)[0]
              count += len(idx)
              self.groupintlab[idx] = np.where(
                  self.groupsunique == name
              )[0]
          if count != self.data.shape[0]:
              # raise ValueError('group_order does not contain all groups')
              # warn and keep only observations with label in group_order
              import warnings
  
              warnings.warn(
                  "group_order does not contain all groups:"
                  + " dropping observations",
                  ValueWarning,
              )
  
              mask_keep = self.groupintlab != -999
              self.groupintlab = self.groupintlab[mask_keep]
              self.data = self.data[mask_keep]
              self.groups = self.groups[mask_keep]
  
      if len(self.groupsunique) < 2:
          raise ValueError(
              "2 or more groups required for multiple comparisons"
          )
  
      self.datali = [
          self.data[self.groups == k] for k in self.groupsunique
      ]
      self.pairindices = np.triu_indices(
          len(self.groupsunique), 1
      )  # tuple
      self.nobs = self.data.shape[0]
      self.ngroups = len(self.groupsunique)
  
imports: from collections import namedtuple
  from statsmodels.compat.python import lzip, lrange
  import copy
  import math
  import numpy
  from numpy.testing import assert_almost_equal, assert_equal
  from scipy import stats, interpolate
  from statsmodels.iolib.table import SimpleTable
  from statsmodels.stats.multitest import multipletests, _ecdf, fdrcorrection, fdrcorrection_twostage
  from statsmodels.graphics import utils
  from statsmodels.tools.sm_exceptions import ValueWarning
label_desc: Use image node_id 1 to create a new MultiComparison object  with example: obj = MultiComparison(data, groups, group_order)