Path: blob/master/ invest-robot-contest_TinkoffBotTwitch-main/venv/lib/python3.8/site-packages/numpy/lib/arraysetops.py
7763 views
"""1Set operations for arrays based on sorting.23Notes4-----56For floating point arrays, inaccurate results may appear due to usual round-off7and floating point comparison issues.89Speed could be gained in some operations by an implementation of10`numpy.sort`, that can provide directly the permutation vectors, thus avoiding11calls to `numpy.argsort`.1213Original author: Robert Cimrman1415"""16import functools1718import numpy as np19from numpy.core import overrides202122array_function_dispatch = functools.partial(23overrides.array_function_dispatch, module='numpy')242526__all__ = [27'ediff1d', 'intersect1d', 'setxor1d', 'union1d', 'setdiff1d', 'unique',28'in1d', 'isin'29]303132def _ediff1d_dispatcher(ary, to_end=None, to_begin=None):33return (ary, to_end, to_begin)343536@array_function_dispatch(_ediff1d_dispatcher)37def ediff1d(ary, to_end=None, to_begin=None):38"""39The differences between consecutive elements of an array.4041Parameters42----------43ary : array_like44If necessary, will be flattened before the differences are taken.45to_end : array_like, optional46Number(s) to append at the end of the returned differences.47to_begin : array_like, optional48Number(s) to prepend at the beginning of the returned differences.4950Returns51-------52ediff1d : ndarray53The differences. Loosely, this is ``ary.flat[1:] - ary.flat[:-1]``.5455See Also56--------57diff, gradient5859Notes60-----61When applied to masked arrays, this function drops the mask information62if the `to_begin` and/or `to_end` parameters are used.6364Examples65--------66>>> x = np.array([1, 2, 4, 7, 0])67>>> np.ediff1d(x)68array([ 1, 2, 3, -7])6970>>> np.ediff1d(x, to_begin=-99, to_end=np.array([88, 99]))71array([-99, 1, 2, ..., -7, 88, 99])7273The returned array is always 1D.7475>>> y = [[1, 2, 4], [1, 6, 24]]76>>> np.ediff1d(y)77array([ 1, 2, -3, 5, 18])7879"""80# force a 1d array81ary = np.asanyarray(ary).ravel()8283# enforce that the dtype of `ary` is used for the output84dtype_req = ary.dtype8586# fast track default case87if to_begin is None and to_end is None:88return ary[1:] - ary[:-1]8990if to_begin is None:91l_begin = 092else:93to_begin = np.asanyarray(to_begin)94if not np.can_cast(to_begin, dtype_req, casting="same_kind"):95raise TypeError("dtype of `to_begin` must be compatible "96"with input `ary` under the `same_kind` rule.")9798to_begin = to_begin.ravel()99l_begin = len(to_begin)100101if to_end is None:102l_end = 0103else:104to_end = np.asanyarray(to_end)105if not np.can_cast(to_end, dtype_req, casting="same_kind"):106raise TypeError("dtype of `to_end` must be compatible "107"with input `ary` under the `same_kind` rule.")108109to_end = to_end.ravel()110l_end = len(to_end)111112# do the calculation in place and copy to_begin and to_end113l_diff = max(len(ary) - 1, 0)114result = np.empty(l_diff + l_begin + l_end, dtype=ary.dtype)115result = ary.__array_wrap__(result)116if l_begin > 0:117result[:l_begin] = to_begin118if l_end > 0:119result[l_begin + l_diff:] = to_end120np.subtract(ary[1:], ary[:-1], result[l_begin:l_begin + l_diff])121return result122123124def _unpack_tuple(x):125""" Unpacks one-element tuples for use as return values """126if len(x) == 1:127return x[0]128else:129return x130131132def _unique_dispatcher(ar, return_index=None, return_inverse=None,133return_counts=None, axis=None):134return (ar,)135136137@array_function_dispatch(_unique_dispatcher)138def unique(ar, return_index=False, return_inverse=False,139return_counts=False, axis=None):140"""141Find the unique elements of an array.142143Returns the sorted unique elements of an array. There are three optional144outputs in addition to the unique elements:145146* the indices of the input array that give the unique values147* the indices of the unique array that reconstruct the input array148* the number of times each unique value comes up in the input array149150Parameters151----------152ar : array_like153Input array. Unless `axis` is specified, this will be flattened if it154is not already 1-D.155return_index : bool, optional156If True, also return the indices of `ar` (along the specified axis,157if provided, or in the flattened array) that result in the unique array.158return_inverse : bool, optional159If True, also return the indices of the unique array (for the specified160axis, if provided) that can be used to reconstruct `ar`.161return_counts : bool, optional162If True, also return the number of times each unique item appears163in `ar`.164165.. versionadded:: 1.9.0166167axis : int or None, optional168The axis to operate on. If None, `ar` will be flattened. If an integer,169the subarrays indexed by the given axis will be flattened and treated170as the elements of a 1-D array with the dimension of the given axis,171see the notes for more details. Object arrays or structured arrays172that contain objects are not supported if the `axis` kwarg is used. The173default is None.174175.. versionadded:: 1.13.0176177Returns178-------179unique : ndarray180The sorted unique values.181unique_indices : ndarray, optional182The indices of the first occurrences of the unique values in the183original array. Only provided if `return_index` is True.184unique_inverse : ndarray, optional185The indices to reconstruct the original array from the186unique array. Only provided if `return_inverse` is True.187unique_counts : ndarray, optional188The number of times each of the unique values comes up in the189original array. Only provided if `return_counts` is True.190191.. versionadded:: 1.9.0192193See Also194--------195numpy.lib.arraysetops : Module with a number of other functions for196performing set operations on arrays.197repeat : Repeat elements of an array.198199Notes200-----201When an axis is specified the subarrays indexed by the axis are sorted.202This is done by making the specified axis the first dimension of the array203(move the axis to the first dimension to keep the order of the other axes)204and then flattening the subarrays in C order. The flattened subarrays are205then viewed as a structured type with each element given a label, with the206effect that we end up with a 1-D array of structured types that can be207treated in the same way as any other 1-D array. The result is that the208flattened subarrays are sorted in lexicographic order starting with the209first element.210211.. versionchanged: NumPy 1.21212If nan values are in the input array, a single nan is put213to the end of the sorted unique values.214215Also for complex arrays all NaN values are considered equivalent216(no matter whether the NaN is in the real or imaginary part).217As the representant for the returned array the smallest one in the218lexicographical order is chosen - see np.sort for how the lexicographical219order is defined for complex arrays.220221Examples222--------223>>> np.unique([1, 1, 2, 2, 3, 3])224array([1, 2, 3])225>>> a = np.array([[1, 1], [2, 3]])226>>> np.unique(a)227array([1, 2, 3])228229Return the unique rows of a 2D array230231>>> a = np.array([[1, 0, 0], [1, 0, 0], [2, 3, 4]])232>>> np.unique(a, axis=0)233array([[1, 0, 0], [2, 3, 4]])234235Return the indices of the original array that give the unique values:236237>>> a = np.array(['a', 'b', 'b', 'c', 'a'])238>>> u, indices = np.unique(a, return_index=True)239>>> u240array(['a', 'b', 'c'], dtype='<U1')241>>> indices242array([0, 1, 3])243>>> a[indices]244array(['a', 'b', 'c'], dtype='<U1')245246Reconstruct the input array from the unique values and inverse:247248>>> a = np.array([1, 2, 6, 4, 2, 3, 2])249>>> u, indices = np.unique(a, return_inverse=True)250>>> u251array([1, 2, 3, 4, 6])252>>> indices253array([0, 1, 4, 3, 1, 2, 1])254>>> u[indices]255array([1, 2, 6, 4, 2, 3, 2])256257Reconstruct the input values from the unique values and counts:258259>>> a = np.array([1, 2, 6, 4, 2, 3, 2])260>>> values, counts = np.unique(a, return_counts=True)261>>> values262array([1, 2, 3, 4, 6])263>>> counts264array([1, 3, 1, 1, 1])265>>> np.repeat(values, counts)266array([1, 2, 2, 2, 3, 4, 6]) # original order not preserved267268"""269ar = np.asanyarray(ar)270if axis is None:271ret = _unique1d(ar, return_index, return_inverse, return_counts)272return _unpack_tuple(ret)273274# axis was specified and not None275try:276ar = np.moveaxis(ar, axis, 0)277except np.AxisError:278# this removes the "axis1" or "axis2" prefix from the error message279raise np.AxisError(axis, ar.ndim) from None280281# Must reshape to a contiguous 2D array for this to work...282orig_shape, orig_dtype = ar.shape, ar.dtype283ar = ar.reshape(orig_shape[0], np.prod(orig_shape[1:], dtype=np.intp))284ar = np.ascontiguousarray(ar)285dtype = [('f{i}'.format(i=i), ar.dtype) for i in range(ar.shape[1])]286287# At this point, `ar` has shape `(n, m)`, and `dtype` is a structured288# data type with `m` fields where each field has the data type of `ar`.289# In the following, we create the array `consolidated`, which has290# shape `(n,)` with data type `dtype`.291try:292if ar.shape[1] > 0:293consolidated = ar.view(dtype)294else:295# If ar.shape[1] == 0, then dtype will be `np.dtype([])`, which is296# a data type with itemsize 0, and the call `ar.view(dtype)` will297# fail. Instead, we'll use `np.empty` to explicitly create the298# array with shape `(len(ar),)`. Because `dtype` in this case has299# itemsize 0, the total size of the result is still 0 bytes.300consolidated = np.empty(len(ar), dtype=dtype)301except TypeError as e:302# There's no good way to do this for object arrays, etc...303msg = 'The axis argument to unique is not supported for dtype {dt}'304raise TypeError(msg.format(dt=ar.dtype)) from e305306def reshape_uniq(uniq):307n = len(uniq)308uniq = uniq.view(orig_dtype)309uniq = uniq.reshape(n, *orig_shape[1:])310uniq = np.moveaxis(uniq, 0, axis)311return uniq312313output = _unique1d(consolidated, return_index,314return_inverse, return_counts)315output = (reshape_uniq(output[0]),) + output[1:]316return _unpack_tuple(output)317318319def _unique1d(ar, return_index=False, return_inverse=False,320return_counts=False):321"""322Find the unique elements of an array, ignoring shape.323"""324ar = np.asanyarray(ar).flatten()325326optional_indices = return_index or return_inverse327328if optional_indices:329perm = ar.argsort(kind='mergesort' if return_index else 'quicksort')330aux = ar[perm]331else:332ar.sort()333aux = ar334mask = np.empty(aux.shape, dtype=np.bool_)335mask[:1] = True336if aux.shape[0] > 0 and aux.dtype.kind in "cfmM" and np.isnan(aux[-1]):337if aux.dtype.kind == "c": # for complex all NaNs are considered equivalent338aux_firstnan = np.searchsorted(np.isnan(aux), True, side='left')339else:340aux_firstnan = np.searchsorted(aux, aux[-1], side='left')341if aux_firstnan > 0:342mask[1:aux_firstnan] = (343aux[1:aux_firstnan] != aux[:aux_firstnan - 1])344mask[aux_firstnan] = True345mask[aux_firstnan + 1:] = False346else:347mask[1:] = aux[1:] != aux[:-1]348349ret = (aux[mask],)350if return_index:351ret += (perm[mask],)352if return_inverse:353imask = np.cumsum(mask) - 1354inv_idx = np.empty(mask.shape, dtype=np.intp)355inv_idx[perm] = imask356ret += (inv_idx,)357if return_counts:358idx = np.concatenate(np.nonzero(mask) + ([mask.size],))359ret += (np.diff(idx),)360return ret361362363def _intersect1d_dispatcher(364ar1, ar2, assume_unique=None, return_indices=None):365return (ar1, ar2)366367368@array_function_dispatch(_intersect1d_dispatcher)369def intersect1d(ar1, ar2, assume_unique=False, return_indices=False):370"""371Find the intersection of two arrays.372373Return the sorted, unique values that are in both of the input arrays.374375Parameters376----------377ar1, ar2 : array_like378Input arrays. Will be flattened if not already 1D.379assume_unique : bool380If True, the input arrays are both assumed to be unique, which381can speed up the calculation. If True but ``ar1`` or ``ar2`` are not382unique, incorrect results and out-of-bounds indices could result.383Default is False.384return_indices : bool385If True, the indices which correspond to the intersection of the two386arrays are returned. The first instance of a value is used if there are387multiple. Default is False.388389.. versionadded:: 1.15.0390391Returns392-------393intersect1d : ndarray394Sorted 1D array of common and unique elements.395comm1 : ndarray396The indices of the first occurrences of the common values in `ar1`.397Only provided if `return_indices` is True.398comm2 : ndarray399The indices of the first occurrences of the common values in `ar2`.400Only provided if `return_indices` is True.401402403See Also404--------405numpy.lib.arraysetops : Module with a number of other functions for406performing set operations on arrays.407408Examples409--------410>>> np.intersect1d([1, 3, 4, 3], [3, 1, 2, 1])411array([1, 3])412413To intersect more than two arrays, use functools.reduce:414415>>> from functools import reduce416>>> reduce(np.intersect1d, ([1, 3, 4, 3], [3, 1, 2, 1], [6, 3, 4, 2]))417array([3])418419To return the indices of the values common to the input arrays420along with the intersected values:421422>>> x = np.array([1, 1, 2, 3, 4])423>>> y = np.array([2, 1, 4, 6])424>>> xy, x_ind, y_ind = np.intersect1d(x, y, return_indices=True)425>>> x_ind, y_ind426(array([0, 2, 4]), array([1, 0, 2]))427>>> xy, x[x_ind], y[y_ind]428(array([1, 2, 4]), array([1, 2, 4]), array([1, 2, 4]))429430"""431ar1 = np.asanyarray(ar1)432ar2 = np.asanyarray(ar2)433434if not assume_unique:435if return_indices:436ar1, ind1 = unique(ar1, return_index=True)437ar2, ind2 = unique(ar2, return_index=True)438else:439ar1 = unique(ar1)440ar2 = unique(ar2)441else:442ar1 = ar1.ravel()443ar2 = ar2.ravel()444445aux = np.concatenate((ar1, ar2))446if return_indices:447aux_sort_indices = np.argsort(aux, kind='mergesort')448aux = aux[aux_sort_indices]449else:450aux.sort()451452mask = aux[1:] == aux[:-1]453int1d = aux[:-1][mask]454455if return_indices:456ar1_indices = aux_sort_indices[:-1][mask]457ar2_indices = aux_sort_indices[1:][mask] - ar1.size458if not assume_unique:459ar1_indices = ind1[ar1_indices]460ar2_indices = ind2[ar2_indices]461462return int1d, ar1_indices, ar2_indices463else:464return int1d465466467def _setxor1d_dispatcher(ar1, ar2, assume_unique=None):468return (ar1, ar2)469470471@array_function_dispatch(_setxor1d_dispatcher)472def setxor1d(ar1, ar2, assume_unique=False):473"""474Find the set exclusive-or of two arrays.475476Return the sorted, unique values that are in only one (not both) of the477input arrays.478479Parameters480----------481ar1, ar2 : array_like482Input arrays.483assume_unique : bool484If True, the input arrays are both assumed to be unique, which485can speed up the calculation. Default is False.486487Returns488-------489setxor1d : ndarray490Sorted 1D array of unique values that are in only one of the input491arrays.492493Examples494--------495>>> a = np.array([1, 2, 3, 2, 4])496>>> b = np.array([2, 3, 5, 7, 5])497>>> np.setxor1d(a,b)498array([1, 4, 5, 7])499500"""501if not assume_unique:502ar1 = unique(ar1)503ar2 = unique(ar2)504505aux = np.concatenate((ar1, ar2))506if aux.size == 0:507return aux508509aux.sort()510flag = np.concatenate(([True], aux[1:] != aux[:-1], [True]))511return aux[flag[1:] & flag[:-1]]512513514def _in1d_dispatcher(ar1, ar2, assume_unique=None, invert=None):515return (ar1, ar2)516517518@array_function_dispatch(_in1d_dispatcher)519def in1d(ar1, ar2, assume_unique=False, invert=False):520"""521Test whether each element of a 1-D array is also present in a second array.522523Returns a boolean array the same length as `ar1` that is True524where an element of `ar1` is in `ar2` and False otherwise.525526We recommend using :func:`isin` instead of `in1d` for new code.527528Parameters529----------530ar1 : (M,) array_like531Input array.532ar2 : array_like533The values against which to test each value of `ar1`.534assume_unique : bool, optional535If True, the input arrays are both assumed to be unique, which536can speed up the calculation. Default is False.537invert : bool, optional538If True, the values in the returned array are inverted (that is,539False where an element of `ar1` is in `ar2` and True otherwise).540Default is False. ``np.in1d(a, b, invert=True)`` is equivalent541to (but is faster than) ``np.invert(in1d(a, b))``.542543.. versionadded:: 1.8.0544545Returns546-------547in1d : (M,) ndarray, bool548The values `ar1[in1d]` are in `ar2`.549550See Also551--------552isin : Version of this function that preserves the553shape of ar1.554numpy.lib.arraysetops : Module with a number of other functions for555performing set operations on arrays.556557Notes558-----559`in1d` can be considered as an element-wise function version of the560python keyword `in`, for 1-D sequences. ``in1d(a, b)`` is roughly561equivalent to ``np.array([item in b for item in a])``.562However, this idea fails if `ar2` is a set, or similar (non-sequence)563container: As ``ar2`` is converted to an array, in those cases564``asarray(ar2)`` is an object array rather than the expected array of565contained values.566567.. versionadded:: 1.4.0568569Examples570--------571>>> test = np.array([0, 1, 2, 5, 0])572>>> states = [0, 2]573>>> mask = np.in1d(test, states)574>>> mask575array([ True, False, True, False, True])576>>> test[mask]577array([0, 2, 0])578>>> mask = np.in1d(test, states, invert=True)579>>> mask580array([False, True, False, True, False])581>>> test[mask]582array([1, 5])583"""584# Ravel both arrays, behavior for the first array could be different585ar1 = np.asarray(ar1).ravel()586ar2 = np.asarray(ar2).ravel()587588# Ensure that iteration through object arrays yields size-1 arrays589if ar2.dtype == object:590ar2 = ar2.reshape(-1, 1)591592# Check if one of the arrays may contain arbitrary objects593contains_object = ar1.dtype.hasobject or ar2.dtype.hasobject594595# This code is run when596# a) the first condition is true, making the code significantly faster597# b) the second condition is true (i.e. `ar1` or `ar2` may contain598# arbitrary objects), since then sorting is not guaranteed to work599if len(ar2) < 10 * len(ar1) ** 0.145 or contains_object:600if invert:601mask = np.ones(len(ar1), dtype=bool)602for a in ar2:603mask &= (ar1 != a)604else:605mask = np.zeros(len(ar1), dtype=bool)606for a in ar2:607mask |= (ar1 == a)608return mask609610# Otherwise use sorting611if not assume_unique:612ar1, rev_idx = np.unique(ar1, return_inverse=True)613ar2 = np.unique(ar2)614615ar = np.concatenate((ar1, ar2))616# We need this to be a stable sort, so always use 'mergesort'617# here. The values from the first array should always come before618# the values from the second array.619order = ar.argsort(kind='mergesort')620sar = ar[order]621if invert:622bool_ar = (sar[1:] != sar[:-1])623else:624bool_ar = (sar[1:] == sar[:-1])625flag = np.concatenate((bool_ar, [invert]))626ret = np.empty(ar.shape, dtype=bool)627ret[order] = flag628629if assume_unique:630return ret[:len(ar1)]631else:632return ret[rev_idx]633634635def _isin_dispatcher(element, test_elements, assume_unique=None, invert=None):636return (element, test_elements)637638639@array_function_dispatch(_isin_dispatcher)640def isin(element, test_elements, assume_unique=False, invert=False):641"""642Calculates `element in test_elements`, broadcasting over `element` only.643Returns a boolean array of the same shape as `element` that is True644where an element of `element` is in `test_elements` and False otherwise.645646Parameters647----------648element : array_like649Input array.650test_elements : array_like651The values against which to test each value of `element`.652This argument is flattened if it is an array or array_like.653See notes for behavior with non-array-like parameters.654assume_unique : bool, optional655If True, the input arrays are both assumed to be unique, which656can speed up the calculation. Default is False.657invert : bool, optional658If True, the values in the returned array are inverted, as if659calculating `element not in test_elements`. Default is False.660``np.isin(a, b, invert=True)`` is equivalent to (but faster661than) ``np.invert(np.isin(a, b))``.662663Returns664-------665isin : ndarray, bool666Has the same shape as `element`. The values `element[isin]`667are in `test_elements`.668669See Also670--------671in1d : Flattened version of this function.672numpy.lib.arraysetops : Module with a number of other functions for673performing set operations on arrays.674675Notes676-----677678`isin` is an element-wise function version of the python keyword `in`.679``isin(a, b)`` is roughly equivalent to680``np.array([item in b for item in a])`` if `a` and `b` are 1-D sequences.681682`element` and `test_elements` are converted to arrays if they are not683already. If `test_elements` is a set (or other non-sequence collection)684it will be converted to an object array with one element, rather than an685array of the values contained in `test_elements`. This is a consequence686of the `array` constructor's way of handling non-sequence collections.687Converting the set to a list usually gives the desired behavior.688689.. versionadded:: 1.13.0690691Examples692--------693>>> element = 2*np.arange(4).reshape((2, 2))694>>> element695array([[0, 2],696[4, 6]])697>>> test_elements = [1, 2, 4, 8]698>>> mask = np.isin(element, test_elements)699>>> mask700array([[False, True],701[ True, False]])702>>> element[mask]703array([2, 4])704705The indices of the matched values can be obtained with `nonzero`:706707>>> np.nonzero(mask)708(array([0, 1]), array([1, 0]))709710The test can also be inverted:711712>>> mask = np.isin(element, test_elements, invert=True)713>>> mask714array([[ True, False],715[False, True]])716>>> element[mask]717array([0, 6])718719Because of how `array` handles sets, the following does not720work as expected:721722>>> test_set = {1, 2, 4, 8}723>>> np.isin(element, test_set)724array([[False, False],725[False, False]])726727Casting the set to a list gives the expected result:728729>>> np.isin(element, list(test_set))730array([[False, True],731[ True, False]])732"""733element = np.asarray(element)734return in1d(element, test_elements, assume_unique=assume_unique,735invert=invert).reshape(element.shape)736737738def _union1d_dispatcher(ar1, ar2):739return (ar1, ar2)740741742@array_function_dispatch(_union1d_dispatcher)743def union1d(ar1, ar2):744"""745Find the union of two arrays.746747Return the unique, sorted array of values that are in either of the two748input arrays.749750Parameters751----------752ar1, ar2 : array_like753Input arrays. They are flattened if they are not already 1D.754755Returns756-------757union1d : ndarray758Unique, sorted union of the input arrays.759760See Also761--------762numpy.lib.arraysetops : Module with a number of other functions for763performing set operations on arrays.764765Examples766--------767>>> np.union1d([-1, 0, 1], [-2, 0, 2])768array([-2, -1, 0, 1, 2])769770To find the union of more than two arrays, use functools.reduce:771772>>> from functools import reduce773>>> reduce(np.union1d, ([1, 3, 4, 3], [3, 1, 2, 1], [6, 3, 4, 2]))774array([1, 2, 3, 4, 6])775"""776return unique(np.concatenate((ar1, ar2), axis=None))777778779def _setdiff1d_dispatcher(ar1, ar2, assume_unique=None):780return (ar1, ar2)781782783@array_function_dispatch(_setdiff1d_dispatcher)784def setdiff1d(ar1, ar2, assume_unique=False):785"""786Find the set difference of two arrays.787788Return the unique values in `ar1` that are not in `ar2`.789790Parameters791----------792ar1 : array_like793Input array.794ar2 : array_like795Input comparison array.796assume_unique : bool797If True, the input arrays are both assumed to be unique, which798can speed up the calculation. Default is False.799800Returns801-------802setdiff1d : ndarray8031D array of values in `ar1` that are not in `ar2`. The result804is sorted when `assume_unique=False`, but otherwise only sorted805if the input is sorted.806807See Also808--------809numpy.lib.arraysetops : Module with a number of other functions for810performing set operations on arrays.811812Examples813--------814>>> a = np.array([1, 2, 3, 2, 4, 1])815>>> b = np.array([3, 4, 5, 6])816>>> np.setdiff1d(a, b)817array([1, 2])818819"""820if assume_unique:821ar1 = np.asarray(ar1).ravel()822else:823ar1 = unique(ar1)824ar2 = unique(ar2)825return ar1[in1d(ar1, ar2, assume_unique=True, invert=True)]826827828