def __init__(self, endog, exog, groups, time=None, family=None,
                 cov_struct=None, missing='none', offset=None,
                 exposure=None, dep_data=None, constraint=None,
                 update_dep=True, weights=None, **kwargs):

        if (family is not None) and not isinstance(family.link, tuple(family.safe_links)):
            import warnings
            warnings.warn("The %s link function does not respect the domain of the %s family." %
                          (family.link.__class__.__name__, family.__class__.__name__))

        self.missing = missing
        self.dep_data = dep_data
        self.constraint = constraint
        self.update_dep = update_dep

        groups = np.array(groups) # in case groups is pandas
        # Pass groups, time, offset, and dep_data so they are
        # processed for missing data along with endog and exog.
        # Calling super creates self.exog, self.endog, etc. as
        # ndarrays and the original exog, endog, etc. are
        # self.data.endog, etc.
        super(GEE, self).__init__(endog, exog, groups=groups,
                                  time=time, offset=offset,
                                  exposure=exposure, weights=weights,
                                  dep_data=dep_data, missing=missing,
                                  **kwargs)

        self._init_keys.extend(["update_dep", "constraint", "family",
                                "cov_struct"])

        # Handle the family argument
        if family is None:
            family = families.Gaussian()
        else:
            if not issubclass(family.__class__, families.Family):
                raise ValueError("GEE: `family` must be a genmod "
                                 "family instance")
        self.family = family

        # Handle the cov_struct argument
        if cov_struct is None:
            cov_struct = cov_structs.Independence()
        else:
            if not issubclass(cov_struct.__class__, cov_structs.CovStruct):
                raise ValueError("GEE: `cov_struct` must be a genmod "
                                 "cov_struct instance")

        self.cov_struct = cov_struct

        # Handle the offset and exposure
        self._offset_exposure = None
        if offset is not None:
            self._offset_exposure = self.offset.copy()
            self.offset = offset
        if exposure is not None:
            if not isinstance(self.family.link, families.links.Log):
                raise ValueError("exposure can only be used with the log link function")
            if self._offset_exposure is not None:
                self._offset_exposure += np.log(exposure)
            else:
                self._offset_exposure = np.log(exposure)
            self.exposure = exposure

        # Handle the constraint
        self.constraint = None
        if constraint is not None:
            if len(constraint) != 2:
                raise ValueError("GEE: `constraint` must be a 2-tuple.")
            if constraint[0].shape[1] != self.exog.shape[1]:
                raise ValueError("GEE: the left hand side of the "
                   "constraint must have the same number of columns "
                   "as the exog matrix.")
            self.constraint = ParameterConstraint(constraint[0],
                                                  constraint[1],
                                                  self.exog)

            if self._offset_exposure is not None:
                self._offset_exposure += self.constraint.offset_increment()
            else:
                self._offset_exposure = self.constraint.offset_increment().copy()
            self.exog = self.constraint.reduced_exog()

        # Create list of row indices for each group
        group_labels, ix = np.unique(self.groups, return_inverse=True)
        se = pd.Series(index=np.arange(len(ix)))
        gb = se.groupby(ix).groups
        dk = [(lb, np.asarray(gb[k])) for k,lb in enumerate(group_labels)]
        self.group_indices = dict(dk)
        self.group_labels = group_labels

        # Convert the data to the internal representation, which is a
        # list of arrays, corresponding to the groups.
        self.endog_li = self.cluster_list(self.endog)
        self.exog_li = self.cluster_list(self.exog)

        if self.weights is not None:
            self.weights_li = self.cluster_list(self.weights)
            self.weights_li = [x[0] for x in self.weights_li]
            self.weights_li = np.asarray(self.weights_li)

        self.num_group = len(self.endog_li)

        # Time defaults to a 1d grid with equal spacing
        if self.time is not None:
            self.time = np.asarray(self.time, np.float64)
            if self.time.ndim == 1:
                self.time = self.time[:,None]
            self.time_li = self.cluster_list(self.time)
        else:
            self.time_li = \
                [np.arange(len(y), dtype=np.float64)[:, None]
                 for y in self.endog_li]
            self.time = np.concatenate(self.time_li)

        if self._offset_exposure is not None:
            self.offset_li = self.cluster_list(self._offset_exposure)
        else:
            self.offset_li = None
        if constraint is not None:
            self.constraint.exog_fulltrans_li = \
                self.cluster_list(self.constraint.exog_fulltrans)

        self.family = family

        self.cov_struct.initialize(self)

        # Total sample size
        group_ns = [len(y) for y in self.endog_li]
        self.nobs = sum(group_ns)
        # The following are column based, not on rank see #1928
        self.df_model = self.exog.shape[1] - 1  # assumes constant
        self.df_resid = self.nobs - self.exog.shape[1]

        # Skip the covariance updates if all groups have a single
        # observation (reduces to fitting a GLM).
        maxgroup = max([len(x) for x in self.endog_li])
        if maxgroup == 1:
            self.update_dep = False

    # Override to allow groups and time to be passed as variable
    # names.
dataset/ETHPy150Open statsmodels/statsmodels/statsmodels/genmod/generalized_estimating_equations.py/GEE.__init__/original