def combine_faster(files: List[str], output_file: str, file_attrs: Dict[str, str] = None, selections: List[np.ndarray] = None, key: str = None, skip_attrs: List[str] = None) -> None:
if file_attrs is None:<EOL><INDENT>file_attrs = {}<EOL><DEDENT>if len(files) == <NUM_LIT:0>:<EOL><INDENT>raise ValueError("<STR_LIT>")<EOL><DEDENT>if selections is None:<EOL><INDENT>selections = [None for _ in files]  <EOL><DEDENT>n_cells = <NUM_LIT:0><EOL>n_genes = <NUM_LIT:0><EOL>for f, s in zip(files, selections):<EOL><INDENT>with loompy.connect(f, "<STR_LIT:r>") as ds:<EOL><INDENT>if n_genes == <NUM_LIT:0>:<EOL><INDENT>n_genes = ds.shape[<NUM_LIT:0>]<EOL><DEDENT>elif n_genes != ds.shape[<NUM_LIT:0>]:<EOL><INDENT>raise ValueError(f"<STR_LIT>")<EOL><DEDENT>if s is None:<EOL><INDENT>n_cells += ds.shape[<NUM_LIT:1>]<EOL><DEDENT>else:<EOL><INDENT>n_cells += s.sum()<EOL><DEDENT><DEDENT><DEDENT>col_attrs: Dict[str, np.ndarray] = {}<EOL>ix = <NUM_LIT:0><EOL>with loompy.new(output_file, file_attrs=file_attrs) as dsout:<EOL><INDENT>for f, s in zip(files, selections):<EOL><INDENT>with loompy.connect(f, "<STR_LIT:r>") as ds:<EOL><INDENT>if key is not None:<EOL><INDENT>ordering = np.argsort(ds.ra[key])<EOL><DEDENT>dsout.shape = (ds.shape[<NUM_LIT:0>], n_cells)  <EOL>n_selected = s.sum()<EOL>for layer in ds.layers.keys():<EOL><INDENT>if layer not in dsout.layers:<EOL><INDENT>dsout[layer] = ds[layer].dtype.name<EOL><DEDENT>if dsout.layers[layer].dtype != ds[layer].dtype:<EOL><INDENT>raise ValueError(f"<STR_LIT>")<EOL><DEDENT>if key is None:<EOL><INDENT>dsout[layer][:, ix: ix + n_selected] = ds[layer][:, :][:, s]<EOL><DEDENT>else:<EOL><INDENT>dsout[layer][:, ix: ix + n_selected] = ds[layer][:, :][:, s][ordering, :]<EOL><DEDENT><DEDENT>for attr, vals in ds.ca.items():<EOL><INDENT>if attr in skip_attrs:<EOL><INDENT>continue<EOL><DEDENT>if attr in col_attrs:<EOL><INDENT>if col_attrs[attr].dtype != vals.dtype:<EOL><INDENT>raise ValueError(f"<STR_LIT>")<EOL><DEDENT><DEDENT>else:<EOL><INDENT>shape = list(vals.shape)<EOL>shape[<NUM_LIT:0>] = n_cells<EOL>col_attrs[attr] = np.zeros(shape, dtype=vals.dtype)<EOL><DEDENT>col_attrs[attr][ix: ix + n_selected] = vals[s]<EOL><DEDENT>for attr, vals in ds.ra.items():<EOL><INDENT>if attr not in dsout.ra:<EOL><INDENT>if key is None:<EOL><INDENT>dsout.ra[attr] = vals<EOL><DEDENT>else:<EOL><INDENT>dsout.ra[attr] = vals[ordering]<EOL><DEDENT><DEDENT><DEDENT><DEDENT>ix = ix + n_selected<EOL><DEDENT>for attr, vals in col_attrs.items():<EOL><INDENT>dsout.ca[attr] = vals<EOL><DEDENT><DEDENT>
Combine loom files and save as a new loom file

Args:
        files (list of str):    the list of input files (full paths)
        output_file (str):      full path of the output loom file
        file_attrs (dict):      file attributes (title, description, url, etc.)
        selections:				list of indicator arrays (one per file; or None to include all cells for the file) determining which columns to include from each file, or None to include all cells from all files
        key:					row attribute to use as key for ordering the rows, or None to skip ordering
        skip_attrs:				list of column attributes that should not be included in the output

Returns:
        Nothing, but creates a new loom file combining the input files.

        Note that the loom files must have exactly the same
        number of rows, in exactly the same order, and must have exactly the same column attributes.
        Values in layers missing from one or more files will be replaced by zeros

        .. warning::
                The files will be combined without changing
                the ordering of rows or columns. Row attributes will be taken from the first file.
                Hence, if rows are not in the same order in all files, the result may be meaningless.

Remarks:
        This version assumes that the individual files will fit in memory. If you run out of memory, try the standard combine() method.