def split(self, X, y=None, groups=None):
X, y, groups = indexable(X, y, groups)<EOL>cgrs = [~r for r in X]<EOL>condition_structure = defaultdict(set)<EOL>for structure, condition in zip(cgrs, groups):<EOL><INDENT>condition_structure[condition].add(structure)<EOL><DEDENT>train_data = defaultdict(list)<EOL>test_data = []<EOL>for n, (structure, condition) in enumerate(zip(cgrs, groups)):<EOL><INDENT>train_data[structure].append(n)<EOL>if len(condition_structure[condition]) > <NUM_LIT:1>:<EOL><INDENT>test_data.append(n)<EOL><DEDENT><DEDENT>if self.n_splits > len(train_data):<EOL><INDENT>raise ValueError("<STR_LIT>"<EOL>"<STR_LIT>"<EOL>% (self.n_splits, len(train_data)))<EOL><DEDENT>structures_weight = sorted(((x, len(y)) for x, y in train_data.items()), key=lambda x: x[<NUM_LIT:1>], reverse=True)<EOL>fold_mean_size = len(cgrs) // self.n_splits<EOL>if structures_weight[<NUM_LIT:0>][<NUM_LIT:1>] > fold_mean_size:<EOL><INDENT>warning('<STR_LIT>')<EOL><DEDENT>for idx in range(self.n_repeats):<EOL><INDENT>train_folds = [[] for _ in range(self.n_splits)]<EOL>for structure, structure_length in structures_weight:<EOL><INDENT>if self.shuffle:<EOL><INDENT>check_random_state(self.random_state).shuffle(train_folds)<EOL><DEDENT>for fold in train_folds[:-<NUM_LIT:1>]:<EOL><INDENT>if len(fold) + structure_length <= fold_mean_size:<EOL><INDENT>fold.extend(train_data[structure])<EOL>break<EOL><DEDENT>else:<EOL><INDENT>roulette_param = (structure_length - fold_mean_size + len(fold)) / structure_length<EOL>if random() > roulette_param:<EOL><INDENT>fold.extend(train_data[structure])<EOL>break<EOL><DEDENT><DEDENT><DEDENT>else:<EOL><INDENT>train_folds[-<NUM_LIT:1>].extend(train_data[structure])<EOL><DEDENT><DEDENT>test_folds = [[] for _ in range(self.n_splits)]<EOL>for test, train in zip(test_folds, train_folds):<EOL><INDENT>for index in train:<EOL><INDENT>if index in test_data:<EOL><INDENT>test.append(index)<EOL><DEDENT><DEDENT><DEDENT>for i in range(self.n_splits):<EOL><INDENT>train_index = []<EOL>for fold in train_folds[:i]:<EOL><INDENT>train_index.extend(fold)<EOL><DEDENT>for fold in train_folds[i+<NUM_LIT:1>:]:<EOL><INDENT>train_index.extend(fold)<EOL><DEDENT>test_index = test_folds[i]<EOL>yield array(train_index), array(test_index)<EOL><DEDENT><DEDENT>
Generate indices to split data into training and test set.
        Parameters
        ----------
        X : array-like, of length n_samples
            Training data, includes reaction's containers
        y : array-like, of length n_samples
            The target variable for supervised learning problems.
        groups : array-like, with shape (n_samples,)
            Group labels for the samples used while splitting the dataset into
            train/test set.
        Yields
        ------
        train : ndarray
            The training set indices for that split.
        test : ndarray
            The testing set indices for that split.