<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def _threshold_nans(data, tolerate_nans):
 """Thresholds data based on proportion of subjects with NaNs Takes in data and a threshold value (float between 0.0 and 1.0) determining the permissible proportion of subjects with non-NaN values. For example, if threshold=.8, any voxel where >= 80% of subjects have non-NaN values will be left unchanged, while any voxel with < 80% non-NaN values will be assigned all NaN values and included in the nan_mask output. Note that the output data has not been masked and will be same shape as the input data, but may have a different number of NaNs based on the threshold. Parameters data : ndarray (n_TRs x n_voxels x n_subjects) fMRI time series data tolerate_nans : bool or float (0.0 <= threshold <= 1.0) Proportion of subjects with non-NaN values required to keep voxel Returns ------- data : ndarray (n_TRs x n_voxels x n_subjects) fMRI time series data with adjusted NaNs nan_mask : ndarray (n_voxels,) Boolean mask array of voxels with too many NaNs based on threshold """


    nans = np.all(np.any(np.isnan(data), axis=0), axis=1)

    # Check tolerate_nans input and use either mean/nanmean and exclude voxels
    if tolerate_nans is True:
        logger.info("ISC computation will tolerate all NaNs when averaging")

    elif type(tolerate_nans) is float:
        if not 0.0 <= tolerate_nans <= 1.0:
            raise ValueError("If threshold to tolerate NaNs is a float, "
                             "it must be between 0.0 and 1.0; got {0}".format(
                                tolerate_nans))
        nans += ~(np.sum(~np.any(np.isnan(data), axis=0), axis=1) >=
                  data.shape[-1] * tolerate_nans)
        logger.info("ISC computation will tolerate voxels with at least "
                    "{0} non-NaN values: {1} voxels do not meet "
                    "threshold".format(tolerate_nans,
                                       np.sum(nans)))

    else:
        logger.info("ISC computation will not tolerate NaNs when averaging")

    mask = ~nans
    data = data[:, mask, :]

    return data, mask