'Apply trees in the forest to X, return leaf indices.
Parameters
X : array-like or sparse matrix, shape = [n_samples, n_features]
The input samples. Internally, its dtype will be converted to
``dtype=np.float32``. If a sparse matrix is provided, it will be
converted into a sparse ``csr_matrix``.
Returns
X_leaves : array_like, shape = [n_samples, n_estimators]
For each datapoint x in X and for each tree in the forest,
return the index of the leaf x ends up in.'

def apply(self, X):

    X = self._validate_X_predict(X)
    results = Parallel(n_jobs=self.n_jobs, verbose=self.verbose, backend='threading')((delayed(parallel_helper)(tree, 'apply', X, check_input=False) for tree in self.estimators_))
    return np.array(results).T
