def format_percentiles(percentiles):
percentiles = np.asarray(percentiles)<EOL>with np.errstate(invalid='<STR_LIT:ignore>'):<EOL><INDENT>if not is_numeric_dtype(percentiles) or not np.all(percentiles >= <NUM_LIT:0>)or not np.all(percentiles <= <NUM_LIT:1>):<EOL><INDENT>raise ValueError("<STR_LIT>")<EOL><DEDENT><DEDENT>percentiles = <NUM_LIT:100> * percentiles<EOL>int_idx = (percentiles.astype(int) == percentiles)<EOL>if np.all(int_idx):<EOL><INDENT>out = percentiles.astype(int).astype(str)<EOL>return [i + '<STR_LIT:%>' for i in out]<EOL><DEDENT>unique_pcts = np.unique(percentiles)<EOL>to_begin = unique_pcts[<NUM_LIT:0>] if unique_pcts[<NUM_LIT:0>] > <NUM_LIT:0> else None<EOL>to_end = <NUM_LIT:100> - unique_pcts[-<NUM_LIT:1>] if unique_pcts[-<NUM_LIT:1>] < <NUM_LIT:100> else None<EOL>prec = -np.floor(np.log10(np.min(<EOL>np.ediff1d(unique_pcts, to_begin=to_begin, to_end=to_end)<EOL>))).astype(int)<EOL>prec = max(<NUM_LIT:1>, prec)<EOL>out = np.empty_like(percentiles, dtype=object)<EOL>out[int_idx] = percentiles[int_idx].astype(int).astype(str)<EOL>out[~int_idx] = percentiles[~int_idx].round(prec).astype(str)<EOL>return [i + '<STR_LIT:%>' for i in out]<EOL>
Outputs rounded and formatted percentiles.

Parameters
----------
percentiles : list-like, containing floats from interval [0,1]

Returns
-------
formatted : list of strings

Notes
-----
Rounding precision is chosen so that: (1) if any two elements of
``percentiles`` differ, they remain different after rounding
(2) no entry is *rounded* to 0% or 100%.
Any non-integer is always rounded to at least 1 decimal place.

Examples
--------
Keeps all entries different after rounding:

>>> format_percentiles([0.01999, 0.02001, 0.5, 0.666666, 0.9999])
['1.999%', '2.001%', '50%', '66.667%', '99.99%']

No element is rounded to 0% or 100% (unless already equal to it).
Duplicates are allowed:

>>> format_percentiles([0, 0.5, 0.02001, 0.5, 0.666666, 0.9999])
['0%', '50%', '2.0%', '50%', '66.67%', '99.99%']