def nonparam_match_empirical_cdf(initial_array, target_array, ignore_indices=None):
    """
    Matches the empirical CDF of the initial array with the empirical CDF
    of a target array. Initial ranks are conserved, but empirical distribution
    matches the target one. Zero-pixels (i.e. pixels having the minimum value)
    in the initial array are conserved.

    Parameters
    ----------
    initial_array: array_like
        The initial array whose CDF is to be matched with the target.
    target_array: array_like
        The target array
    ignore_indices: array_like, optional
        Indices of pixels in the initial_array which are to be ignored (not
        rescaled) or an array of booleans with True at the pixel locations to
        be ignored in initial_array and False elsewhere.


    Returns
    -------
    output_array: ndarray
        The matched array of the same shape as the initial array.
    """

    if np.all(np.isnan(initial_array)):
        raise ValueError("Initial array contains only nans.")
    if initial_array.size != target_array.size:
        raise ValueError(
            "dimension mismatch between initial_array and target_array: "
            f"initial_array.shape={initial_array.shape}, target_array.shape={target_array.shape}"
        )

    initial_array_copy = np.array(initial_array, dtype=float)
    target_array = np.array(target_array, dtype=float)

    # Determine zero in initial array and set nans to zero
    zvalue = np.nanmin(initial_array_copy)
    if ignore_indices is not None:
        initial_array_copy[ignore_indices] = zvalue
    # Check if there are still nans left after setting the values at ignore_indices to zero.
    if np.any(~np.isfinite(initial_array_copy)):
        raise ValueError(
            "Initial array contains non-finite values outside ignore_indices mask."
        )

    idxzeros = initial_array_copy == zvalue

    # Determine zero of target_array and set nans to zero.
    zvalue_trg = np.nanmin(target_array)
    target_array = np.where(np.isnan(target_array), zvalue_trg, target_array)

    # adjust the fraction of rain in target distribution if the number of
    # nonzeros is greater than in the initial array (the lowest values will be set to zero)
    if np.sum(target_array > zvalue_trg) > np.sum(initial_array_copy > zvalue):
        war = np.sum(initial_array_copy > zvalue) / initial_array_copy.size
        p = np.percentile(target_array, 100 * (1 - war))
        target_array[target_array < p] = zvalue_trg

    # flatten the arrays without copying them
    arrayshape = initial_array_copy.shape
    target_array = target_array.reshape(-1)
    initial_array_copy = initial_array_copy.reshape(-1)

    # rank target values
    order = target_array.argsort()
    ranked = target_array[order]

    # rank initial values order
    orderin = initial_array_copy.argsort()
    ranks = np.empty(len(initial_array_copy), int)
    ranks[orderin] = np.arange(len(initial_array_copy))

    # get ranked values from target and rearrange with the initial order
    output_array = ranked[ranks]

    # reshape to the original array dimensions
    output_array = output_array.reshape(arrayshape)

    # read original zeros
    output_array[idxzeros] = zvalue_trg

    # Put back the original values outside the nan-mask of the target array.
    if ignore_indices is not None:
        output_array[ignore_indices] = initial_array[ignore_indices]
    return output_array
Matches the empirical CDF of the initial array with the empirical CDF
of a target array. Initial ranks are conserved, but empirical distribution
matches the target one. Zero-pixels (i.e. pixels having the minimum value)
in the initial array are conserved.

Parameters
----------
initial_array: array_like
The initial array whose CDF is to be matched with the target.
target_array: array_like
The target array
ignore_indices: array_like, optional
Indices of pixels in the initial_array which are to be ignored (not
rescaled) or an array of booleans with True at the pixel locations to
be ignored in initial_array and False elsewhere.


Returns
-------
output_array: ndarray
The matched array of the same shape as the initial array.
pysteps/postprocessing/probmatching.py