<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def prepare_searchlight_mvpa_data(images, conditions, data_type=np.float32, random=RandomType.NORANDOM):
 """ obtain the data for activity-based voxel selection using Searchlight Average the activity within epochs and z-scoring within subject, while maintaining the 3D brain structure. In order to save memory, the data is processed subject by subject instead of reading all in before processing. Assuming all subjects live in the identical cube. Parameters images: Iterable[SpatialImage] Data. conditions: List[UniqueLabelConditionSpec] Condition specification. data_type Type to cast image to. random: Optional[RandomType] Randomize the image data within subject or not. Returns ------- processed_data: 4D array in shape [brain 3D + epoch] averaged epoch by epoch processed data labels: 1D array contains labels of the data """

    time1 = time.time()
    epoch_info = generate_epochs_info(conditions)
    num_epochs = len(epoch_info)
    processed_data = None
    logger.info(
        'there are %d subjects, and in total %d epochs' %
        (len(conditions), num_epochs)
    )
    labels = np.empty(num_epochs)
    # assign labels
    for idx, epoch in enumerate(epoch_info):
        labels[idx] = epoch[0]
    # counting the epochs per subject for z-scoring
    subject_count = np.zeros(len(conditions), dtype=np.int32)

    logger.info('start to apply masks and separate epochs')
    for sid, f in enumerate(images):
        data = f.get_data().astype(data_type)
        [d1, d2, d3, d4] = data.shape
        if random == RandomType.REPRODUCIBLE:
            data = data.reshape((d1 * d2 * d3, d4))
            _randomize_single_subject(data, seed=sid)
            data = data.reshape((d1, d2, d3, d4))
        elif random == RandomType.UNREPRODUCIBLE:
            data = data.reshape((d1 * d2 * d3, d4))
            _randomize_single_subject(data)
            data = data.reshape((d1, d2, d3, d4))
        if processed_data is None:
            processed_data = np.empty([d1, d2, d3, num_epochs],
                                      dtype=data_type)
        # averaging
        for idx, epoch in enumerate(epoch_info):
            if sid == epoch[1]:
                subject_count[sid] += 1
                processed_data[:, :, :, idx] = \
                    np.mean(data[:, :, :, epoch[2]:epoch[3]], axis=3)

        logger.debug(
            'file %s is loaded and processed, with data shape %s',
            f.get_filename(), data.shape
        )
    # z-scoring
    cur_epoch = 0
    for i in subject_count:
        if i > 1:
            processed_data[:, :, :, cur_epoch:cur_epoch + i] = \
                zscore(processed_data[:, :, :, cur_epoch:cur_epoch + i],
                       axis=3, ddof=0)
        cur_epoch += i
    # if zscore fails (standard deviation is zero),
    # set all values to be zero
    processed_data = np.nan_to_num(processed_data)
    time2 = time.time()
    logger.info(
        'data processed for activity-based voxel selection, takes %.2f s' %
        (time2 - time1)
    )

    return processed_data, labels