CoolFace
Apppublic

Aluode/PerceptionLabPortable

sourceHugging Faceupdated 9mo agoView on Hugging Face
0likes
_unique.py109 linesDownload Raw Back to utils
1# Authors: The scikit-learn developers
2# SPDX-License-Identifier: BSD-3-Clause
3
4import numpy as np
5
6from sklearn.utils._array_api import get_namespace
7
8
9def _attach_unique(y):
10    """Attach unique values of y to y and return the result.
11
12    The result is a view of y, and the metadata (unique) is not attached to y.
13    """
14    if not isinstance(y, np.ndarray):
15        return y
16    try:
17        # avoid recalculating unique in nested calls.
18        if "unique" in y.dtype.metadata:
19            return y
20    except (AttributeError, TypeError):
21        pass
22
23    unique = np.unique(y)
24    unique_dtype = np.dtype(y.dtype, metadata={"unique": unique})
25    return y.view(dtype=unique_dtype)
26
27
28def attach_unique(*ys, return_tuple=False):
29    """Attach unique values of ys to ys and return the results.
30
31    The result is a view of y, and the metadata (unique) is not attached to y.
32
33    IMPORTANT: The output of this function should NEVER be returned in functions.
34    This is to avoid this pattern:
35
36    .. code:: python
37
38        y = np.array([1, 2, 3])
39        y = attach_unique(y)
40        y[1] = -1
41        # now np.unique(y) will be different from cached_unique(y)
42
43    Parameters
44    ----------
45    *ys : sequence of array-like
46        Input data arrays.
47
48    return_tuple : bool, default=False
49        If True, always return a tuple even if there is only one array.
50
51    Returns
52    -------
53    ys : tuple of array-like or array-like
54        Input data with unique values attached.
55    """
56    res = tuple(_attach_unique(y) for y in ys)
57    if len(res) == 1 and not return_tuple:
58        return res[0]
59    return res
60
61
62def _cached_unique(y, xp=None):
63    """Return the unique values of y.
64
65    Use the cached values from dtype.metadata if present.
66
67    This function does NOT cache the values in y, i.e. it doesn't change y.
68
69    Call `attach_unique` to attach the unique values to y.
70    """
71    try:
72        if y.dtype.metadata is not None and "unique" in y.dtype.metadata:
73            return y.dtype.metadata["unique"]
74    except AttributeError:
75        # in case y is not a numpy array
76        pass
77    xp, _ = get_namespace(y, xp=xp)
78    return xp.unique_values(y)
79
80
81def cached_unique(*ys, xp=None):
82    """Return the unique values of ys.
83
84    Use the cached values from dtype.metadata if present.
85
86    This function does NOT cache the values in y, i.e. it doesn't change y.
87
88    Call `attach_unique` to attach the unique values to y.
89
90    Parameters
91    ----------
92    *ys : sequence of array-like
93        Input data arrays.
94
95    xp : module, default=None
96        Precomputed array namespace module. When passed, typically from a caller
97        that has already performed inspection of its own inputs, skips array
98        namespace inspection.
99
100    Returns
101    -------
102    res : tuple of array-like or array-like
103        Unique values of ys.
104    """
105    res = tuple(_cached_unique(y, xp=xp) for y in ys)
106    if len(res) == 1:
107        return res[0]
108    return res
109 
Aluode/PerceptionLabPortable · CoolFace