<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def create_cross_sectional_bootstrap_samples(obs_id_array, alt_id_array, choice_array, num_samples, seed=None):
 """ Determines the unique observations that will be present in each bootstrap sample. This function DOES NOT create the new design matrices or a new long-format dataframe for each bootstrap sample. Note that these will be correct bootstrap samples for cross-sectional datasets. This function will not work correctly for panel datasets. Parameters obs_id_array : 1D ndarray of ints. Each element should denote a unique observation id for the corresponding row of the long format array. alt_id_array : 1D ndarray of ints. Each element should denote a unique alternative id for the corresponding row of the long format array. choice_array : 1D ndarray of ints. Each element should be a one or a zero. The values should denote a whether or not the corresponding alternative in `alt_id_array` was chosen by the observational unit in the corresponding row of `obs_id_array.` num_samples : int. Denotes the number of bootstrap samples that need to be drawn. seed : non-negative int or None, optional. Denotes the random seed to be used in order to ensure reproducibility of the bootstrap sample generation. Default is None. If None, no seed will be used and the generation of the bootstrap samples will (in general) not be reproducible. Returns ------- ids_per_sample : 2D ndarray. Each row represents a complete bootstrap sample. Each column denotes a selected bootstrap observation that comprises the bootstrap sample. The elements of the array denote the observation ids of the chosen observational units. """

    # Determine the units of observation that chose each alternative.
    chosen_alts_to_obs_ids =\
        relate_obs_ids_to_chosen_alts(obs_id_array, alt_id_array, choice_array)

    # Determine the number of unique units of observation per group and overall
    num_obs_per_group, tot_num_obs =\
        get_num_obs_choosing_each_alternative(chosen_alts_to_obs_ids)

    # Initialize the array that will store the observation ids for each sample
    ids_per_sample = np.empty((num_samples, tot_num_obs), dtype=float)

    if seed is not None:
        # Check the validity of the seed argument.
        if not isinstance(seed, int):
            msg = "`boot_seed` MUST be an int."
            raise ValueError(msg)

        # If desiring reproducibility, set the random seed within numpy
        np.random.seed(seed)

    # Initialize a variable to keep track of what column we're on.
    col_idx = 0
    for alt_id in num_obs_per_group:
        # Get the set of observations that chose the current alternative.
        relevant_ids = chosen_alts_to_obs_ids[alt_id]
        # Determine the number of needed resampled ids.
        resample_size = num_obs_per_group[alt_id]
        # Resample, with replacement, observations who chose this alternative.
        current_ids = (np.random.choice(relevant_ids,
                                        size=resample_size * num_samples,
                                        replace=True)
                                .reshape((num_samples, resample_size)))
        # Determine the last column index to use when storing the resampled ids
        end_col = col_idx + resample_size
        # Assign the sampled ids to the correct columns of ids_per_sample
        ids_per_sample[:, col_idx:end_col] = current_ids
        # Update the column index
        col_idx += resample_size

    # Return the resampled observation ids.
    return ids_per_sample