Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
wiseplat
GitHub Repository: wiseplat/python-code
Path: blob/master/ invest-robot-contest_TinkoffBotTwitch-main/venv/lib/python3.8/site-packages/numpy/lib/arraysetops.py
7763 views
1
"""
2
Set operations for arrays based on sorting.
3
4
Notes
5
-----
6
7
For floating point arrays, inaccurate results may appear due to usual round-off
8
and floating point comparison issues.
9
10
Speed could be gained in some operations by an implementation of
11
`numpy.sort`, that can provide directly the permutation vectors, thus avoiding
12
calls to `numpy.argsort`.
13
14
Original author: Robert Cimrman
15
16
"""
17
import functools
18
19
import numpy as np
20
from numpy.core import overrides
21
22
23
array_function_dispatch = functools.partial(
24
overrides.array_function_dispatch, module='numpy')
25
26
27
__all__ = [
28
'ediff1d', 'intersect1d', 'setxor1d', 'union1d', 'setdiff1d', 'unique',
29
'in1d', 'isin'
30
]
31
32
33
def _ediff1d_dispatcher(ary, to_end=None, to_begin=None):
34
return (ary, to_end, to_begin)
35
36
37
@array_function_dispatch(_ediff1d_dispatcher)
38
def ediff1d(ary, to_end=None, to_begin=None):
39
"""
40
The differences between consecutive elements of an array.
41
42
Parameters
43
----------
44
ary : array_like
45
If necessary, will be flattened before the differences are taken.
46
to_end : array_like, optional
47
Number(s) to append at the end of the returned differences.
48
to_begin : array_like, optional
49
Number(s) to prepend at the beginning of the returned differences.
50
51
Returns
52
-------
53
ediff1d : ndarray
54
The differences. Loosely, this is ``ary.flat[1:] - ary.flat[:-1]``.
55
56
See Also
57
--------
58
diff, gradient
59
60
Notes
61
-----
62
When applied to masked arrays, this function drops the mask information
63
if the `to_begin` and/or `to_end` parameters are used.
64
65
Examples
66
--------
67
>>> x = np.array([1, 2, 4, 7, 0])
68
>>> np.ediff1d(x)
69
array([ 1, 2, 3, -7])
70
71
>>> np.ediff1d(x, to_begin=-99, to_end=np.array([88, 99]))
72
array([-99, 1, 2, ..., -7, 88, 99])
73
74
The returned array is always 1D.
75
76
>>> y = [[1, 2, 4], [1, 6, 24]]
77
>>> np.ediff1d(y)
78
array([ 1, 2, -3, 5, 18])
79
80
"""
81
# force a 1d array
82
ary = np.asanyarray(ary).ravel()
83
84
# enforce that the dtype of `ary` is used for the output
85
dtype_req = ary.dtype
86
87
# fast track default case
88
if to_begin is None and to_end is None:
89
return ary[1:] - ary[:-1]
90
91
if to_begin is None:
92
l_begin = 0
93
else:
94
to_begin = np.asanyarray(to_begin)
95
if not np.can_cast(to_begin, dtype_req, casting="same_kind"):
96
raise TypeError("dtype of `to_begin` must be compatible "
97
"with input `ary` under the `same_kind` rule.")
98
99
to_begin = to_begin.ravel()
100
l_begin = len(to_begin)
101
102
if to_end is None:
103
l_end = 0
104
else:
105
to_end = np.asanyarray(to_end)
106
if not np.can_cast(to_end, dtype_req, casting="same_kind"):
107
raise TypeError("dtype of `to_end` must be compatible "
108
"with input `ary` under the `same_kind` rule.")
109
110
to_end = to_end.ravel()
111
l_end = len(to_end)
112
113
# do the calculation in place and copy to_begin and to_end
114
l_diff = max(len(ary) - 1, 0)
115
result = np.empty(l_diff + l_begin + l_end, dtype=ary.dtype)
116
result = ary.__array_wrap__(result)
117
if l_begin > 0:
118
result[:l_begin] = to_begin
119
if l_end > 0:
120
result[l_begin + l_diff:] = to_end
121
np.subtract(ary[1:], ary[:-1], result[l_begin:l_begin + l_diff])
122
return result
123
124
125
def _unpack_tuple(x):
126
""" Unpacks one-element tuples for use as return values """
127
if len(x) == 1:
128
return x[0]
129
else:
130
return x
131
132
133
def _unique_dispatcher(ar, return_index=None, return_inverse=None,
134
return_counts=None, axis=None):
135
return (ar,)
136
137
138
@array_function_dispatch(_unique_dispatcher)
139
def unique(ar, return_index=False, return_inverse=False,
140
return_counts=False, axis=None):
141
"""
142
Find the unique elements of an array.
143
144
Returns the sorted unique elements of an array. There are three optional
145
outputs in addition to the unique elements:
146
147
* the indices of the input array that give the unique values
148
* the indices of the unique array that reconstruct the input array
149
* the number of times each unique value comes up in the input array
150
151
Parameters
152
----------
153
ar : array_like
154
Input array. Unless `axis` is specified, this will be flattened if it
155
is not already 1-D.
156
return_index : bool, optional
157
If True, also return the indices of `ar` (along the specified axis,
158
if provided, or in the flattened array) that result in the unique array.
159
return_inverse : bool, optional
160
If True, also return the indices of the unique array (for the specified
161
axis, if provided) that can be used to reconstruct `ar`.
162
return_counts : bool, optional
163
If True, also return the number of times each unique item appears
164
in `ar`.
165
166
.. versionadded:: 1.9.0
167
168
axis : int or None, optional
169
The axis to operate on. If None, `ar` will be flattened. If an integer,
170
the subarrays indexed by the given axis will be flattened and treated
171
as the elements of a 1-D array with the dimension of the given axis,
172
see the notes for more details. Object arrays or structured arrays
173
that contain objects are not supported if the `axis` kwarg is used. The
174
default is None.
175
176
.. versionadded:: 1.13.0
177
178
Returns
179
-------
180
unique : ndarray
181
The sorted unique values.
182
unique_indices : ndarray, optional
183
The indices of the first occurrences of the unique values in the
184
original array. Only provided if `return_index` is True.
185
unique_inverse : ndarray, optional
186
The indices to reconstruct the original array from the
187
unique array. Only provided if `return_inverse` is True.
188
unique_counts : ndarray, optional
189
The number of times each of the unique values comes up in the
190
original array. Only provided if `return_counts` is True.
191
192
.. versionadded:: 1.9.0
193
194
See Also
195
--------
196
numpy.lib.arraysetops : Module with a number of other functions for
197
performing set operations on arrays.
198
repeat : Repeat elements of an array.
199
200
Notes
201
-----
202
When an axis is specified the subarrays indexed by the axis are sorted.
203
This is done by making the specified axis the first dimension of the array
204
(move the axis to the first dimension to keep the order of the other axes)
205
and then flattening the subarrays in C order. The flattened subarrays are
206
then viewed as a structured type with each element given a label, with the
207
effect that we end up with a 1-D array of structured types that can be
208
treated in the same way as any other 1-D array. The result is that the
209
flattened subarrays are sorted in lexicographic order starting with the
210
first element.
211
212
.. versionchanged: NumPy 1.21
213
If nan values are in the input array, a single nan is put
214
to the end of the sorted unique values.
215
216
Also for complex arrays all NaN values are considered equivalent
217
(no matter whether the NaN is in the real or imaginary part).
218
As the representant for the returned array the smallest one in the
219
lexicographical order is chosen - see np.sort for how the lexicographical
220
order is defined for complex arrays.
221
222
Examples
223
--------
224
>>> np.unique([1, 1, 2, 2, 3, 3])
225
array([1, 2, 3])
226
>>> a = np.array([[1, 1], [2, 3]])
227
>>> np.unique(a)
228
array([1, 2, 3])
229
230
Return the unique rows of a 2D array
231
232
>>> a = np.array([[1, 0, 0], [1, 0, 0], [2, 3, 4]])
233
>>> np.unique(a, axis=0)
234
array([[1, 0, 0], [2, 3, 4]])
235
236
Return the indices of the original array that give the unique values:
237
238
>>> a = np.array(['a', 'b', 'b', 'c', 'a'])
239
>>> u, indices = np.unique(a, return_index=True)
240
>>> u
241
array(['a', 'b', 'c'], dtype='<U1')
242
>>> indices
243
array([0, 1, 3])
244
>>> a[indices]
245
array(['a', 'b', 'c'], dtype='<U1')
246
247
Reconstruct the input array from the unique values and inverse:
248
249
>>> a = np.array([1, 2, 6, 4, 2, 3, 2])
250
>>> u, indices = np.unique(a, return_inverse=True)
251
>>> u
252
array([1, 2, 3, 4, 6])
253
>>> indices
254
array([0, 1, 4, 3, 1, 2, 1])
255
>>> u[indices]
256
array([1, 2, 6, 4, 2, 3, 2])
257
258
Reconstruct the input values from the unique values and counts:
259
260
>>> a = np.array([1, 2, 6, 4, 2, 3, 2])
261
>>> values, counts = np.unique(a, return_counts=True)
262
>>> values
263
array([1, 2, 3, 4, 6])
264
>>> counts
265
array([1, 3, 1, 1, 1])
266
>>> np.repeat(values, counts)
267
array([1, 2, 2, 2, 3, 4, 6]) # original order not preserved
268
269
"""
270
ar = np.asanyarray(ar)
271
if axis is None:
272
ret = _unique1d(ar, return_index, return_inverse, return_counts)
273
return _unpack_tuple(ret)
274
275
# axis was specified and not None
276
try:
277
ar = np.moveaxis(ar, axis, 0)
278
except np.AxisError:
279
# this removes the "axis1" or "axis2" prefix from the error message
280
raise np.AxisError(axis, ar.ndim) from None
281
282
# Must reshape to a contiguous 2D array for this to work...
283
orig_shape, orig_dtype = ar.shape, ar.dtype
284
ar = ar.reshape(orig_shape[0], np.prod(orig_shape[1:], dtype=np.intp))
285
ar = np.ascontiguousarray(ar)
286
dtype = [('f{i}'.format(i=i), ar.dtype) for i in range(ar.shape[1])]
287
288
# At this point, `ar` has shape `(n, m)`, and `dtype` is a structured
289
# data type with `m` fields where each field has the data type of `ar`.
290
# In the following, we create the array `consolidated`, which has
291
# shape `(n,)` with data type `dtype`.
292
try:
293
if ar.shape[1] > 0:
294
consolidated = ar.view(dtype)
295
else:
296
# If ar.shape[1] == 0, then dtype will be `np.dtype([])`, which is
297
# a data type with itemsize 0, and the call `ar.view(dtype)` will
298
# fail. Instead, we'll use `np.empty` to explicitly create the
299
# array with shape `(len(ar),)`. Because `dtype` in this case has
300
# itemsize 0, the total size of the result is still 0 bytes.
301
consolidated = np.empty(len(ar), dtype=dtype)
302
except TypeError as e:
303
# There's no good way to do this for object arrays, etc...
304
msg = 'The axis argument to unique is not supported for dtype {dt}'
305
raise TypeError(msg.format(dt=ar.dtype)) from e
306
307
def reshape_uniq(uniq):
308
n = len(uniq)
309
uniq = uniq.view(orig_dtype)
310
uniq = uniq.reshape(n, *orig_shape[1:])
311
uniq = np.moveaxis(uniq, 0, axis)
312
return uniq
313
314
output = _unique1d(consolidated, return_index,
315
return_inverse, return_counts)
316
output = (reshape_uniq(output[0]),) + output[1:]
317
return _unpack_tuple(output)
318
319
320
def _unique1d(ar, return_index=False, return_inverse=False,
321
return_counts=False):
322
"""
323
Find the unique elements of an array, ignoring shape.
324
"""
325
ar = np.asanyarray(ar).flatten()
326
327
optional_indices = return_index or return_inverse
328
329
if optional_indices:
330
perm = ar.argsort(kind='mergesort' if return_index else 'quicksort')
331
aux = ar[perm]
332
else:
333
ar.sort()
334
aux = ar
335
mask = np.empty(aux.shape, dtype=np.bool_)
336
mask[:1] = True
337
if aux.shape[0] > 0 and aux.dtype.kind in "cfmM" and np.isnan(aux[-1]):
338
if aux.dtype.kind == "c": # for complex all NaNs are considered equivalent
339
aux_firstnan = np.searchsorted(np.isnan(aux), True, side='left')
340
else:
341
aux_firstnan = np.searchsorted(aux, aux[-1], side='left')
342
if aux_firstnan > 0:
343
mask[1:aux_firstnan] = (
344
aux[1:aux_firstnan] != aux[:aux_firstnan - 1])
345
mask[aux_firstnan] = True
346
mask[aux_firstnan + 1:] = False
347
else:
348
mask[1:] = aux[1:] != aux[:-1]
349
350
ret = (aux[mask],)
351
if return_index:
352
ret += (perm[mask],)
353
if return_inverse:
354
imask = np.cumsum(mask) - 1
355
inv_idx = np.empty(mask.shape, dtype=np.intp)
356
inv_idx[perm] = imask
357
ret += (inv_idx,)
358
if return_counts:
359
idx = np.concatenate(np.nonzero(mask) + ([mask.size],))
360
ret += (np.diff(idx),)
361
return ret
362
363
364
def _intersect1d_dispatcher(
365
ar1, ar2, assume_unique=None, return_indices=None):
366
return (ar1, ar2)
367
368
369
@array_function_dispatch(_intersect1d_dispatcher)
370
def intersect1d(ar1, ar2, assume_unique=False, return_indices=False):
371
"""
372
Find the intersection of two arrays.
373
374
Return the sorted, unique values that are in both of the input arrays.
375
376
Parameters
377
----------
378
ar1, ar2 : array_like
379
Input arrays. Will be flattened if not already 1D.
380
assume_unique : bool
381
If True, the input arrays are both assumed to be unique, which
382
can speed up the calculation. If True but ``ar1`` or ``ar2`` are not
383
unique, incorrect results and out-of-bounds indices could result.
384
Default is False.
385
return_indices : bool
386
If True, the indices which correspond to the intersection of the two
387
arrays are returned. The first instance of a value is used if there are
388
multiple. Default is False.
389
390
.. versionadded:: 1.15.0
391
392
Returns
393
-------
394
intersect1d : ndarray
395
Sorted 1D array of common and unique elements.
396
comm1 : ndarray
397
The indices of the first occurrences of the common values in `ar1`.
398
Only provided if `return_indices` is True.
399
comm2 : ndarray
400
The indices of the first occurrences of the common values in `ar2`.
401
Only provided if `return_indices` is True.
402
403
404
See Also
405
--------
406
numpy.lib.arraysetops : Module with a number of other functions for
407
performing set operations on arrays.
408
409
Examples
410
--------
411
>>> np.intersect1d([1, 3, 4, 3], [3, 1, 2, 1])
412
array([1, 3])
413
414
To intersect more than two arrays, use functools.reduce:
415
416
>>> from functools import reduce
417
>>> reduce(np.intersect1d, ([1, 3, 4, 3], [3, 1, 2, 1], [6, 3, 4, 2]))
418
array([3])
419
420
To return the indices of the values common to the input arrays
421
along with the intersected values:
422
423
>>> x = np.array([1, 1, 2, 3, 4])
424
>>> y = np.array([2, 1, 4, 6])
425
>>> xy, x_ind, y_ind = np.intersect1d(x, y, return_indices=True)
426
>>> x_ind, y_ind
427
(array([0, 2, 4]), array([1, 0, 2]))
428
>>> xy, x[x_ind], y[y_ind]
429
(array([1, 2, 4]), array([1, 2, 4]), array([1, 2, 4]))
430
431
"""
432
ar1 = np.asanyarray(ar1)
433
ar2 = np.asanyarray(ar2)
434
435
if not assume_unique:
436
if return_indices:
437
ar1, ind1 = unique(ar1, return_index=True)
438
ar2, ind2 = unique(ar2, return_index=True)
439
else:
440
ar1 = unique(ar1)
441
ar2 = unique(ar2)
442
else:
443
ar1 = ar1.ravel()
444
ar2 = ar2.ravel()
445
446
aux = np.concatenate((ar1, ar2))
447
if return_indices:
448
aux_sort_indices = np.argsort(aux, kind='mergesort')
449
aux = aux[aux_sort_indices]
450
else:
451
aux.sort()
452
453
mask = aux[1:] == aux[:-1]
454
int1d = aux[:-1][mask]
455
456
if return_indices:
457
ar1_indices = aux_sort_indices[:-1][mask]
458
ar2_indices = aux_sort_indices[1:][mask] - ar1.size
459
if not assume_unique:
460
ar1_indices = ind1[ar1_indices]
461
ar2_indices = ind2[ar2_indices]
462
463
return int1d, ar1_indices, ar2_indices
464
else:
465
return int1d
466
467
468
def _setxor1d_dispatcher(ar1, ar2, assume_unique=None):
469
return (ar1, ar2)
470
471
472
@array_function_dispatch(_setxor1d_dispatcher)
473
def setxor1d(ar1, ar2, assume_unique=False):
474
"""
475
Find the set exclusive-or of two arrays.
476
477
Return the sorted, unique values that are in only one (not both) of the
478
input arrays.
479
480
Parameters
481
----------
482
ar1, ar2 : array_like
483
Input arrays.
484
assume_unique : bool
485
If True, the input arrays are both assumed to be unique, which
486
can speed up the calculation. Default is False.
487
488
Returns
489
-------
490
setxor1d : ndarray
491
Sorted 1D array of unique values that are in only one of the input
492
arrays.
493
494
Examples
495
--------
496
>>> a = np.array([1, 2, 3, 2, 4])
497
>>> b = np.array([2, 3, 5, 7, 5])
498
>>> np.setxor1d(a,b)
499
array([1, 4, 5, 7])
500
501
"""
502
if not assume_unique:
503
ar1 = unique(ar1)
504
ar2 = unique(ar2)
505
506
aux = np.concatenate((ar1, ar2))
507
if aux.size == 0:
508
return aux
509
510
aux.sort()
511
flag = np.concatenate(([True], aux[1:] != aux[:-1], [True]))
512
return aux[flag[1:] & flag[:-1]]
513
514
515
def _in1d_dispatcher(ar1, ar2, assume_unique=None, invert=None):
516
return (ar1, ar2)
517
518
519
@array_function_dispatch(_in1d_dispatcher)
520
def in1d(ar1, ar2, assume_unique=False, invert=False):
521
"""
522
Test whether each element of a 1-D array is also present in a second array.
523
524
Returns a boolean array the same length as `ar1` that is True
525
where an element of `ar1` is in `ar2` and False otherwise.
526
527
We recommend using :func:`isin` instead of `in1d` for new code.
528
529
Parameters
530
----------
531
ar1 : (M,) array_like
532
Input array.
533
ar2 : array_like
534
The values against which to test each value of `ar1`.
535
assume_unique : bool, optional
536
If True, the input arrays are both assumed to be unique, which
537
can speed up the calculation. Default is False.
538
invert : bool, optional
539
If True, the values in the returned array are inverted (that is,
540
False where an element of `ar1` is in `ar2` and True otherwise).
541
Default is False. ``np.in1d(a, b, invert=True)`` is equivalent
542
to (but is faster than) ``np.invert(in1d(a, b))``.
543
544
.. versionadded:: 1.8.0
545
546
Returns
547
-------
548
in1d : (M,) ndarray, bool
549
The values `ar1[in1d]` are in `ar2`.
550
551
See Also
552
--------
553
isin : Version of this function that preserves the
554
shape of ar1.
555
numpy.lib.arraysetops : Module with a number of other functions for
556
performing set operations on arrays.
557
558
Notes
559
-----
560
`in1d` can be considered as an element-wise function version of the
561
python keyword `in`, for 1-D sequences. ``in1d(a, b)`` is roughly
562
equivalent to ``np.array([item in b for item in a])``.
563
However, this idea fails if `ar2` is a set, or similar (non-sequence)
564
container: As ``ar2`` is converted to an array, in those cases
565
``asarray(ar2)`` is an object array rather than the expected array of
566
contained values.
567
568
.. versionadded:: 1.4.0
569
570
Examples
571
--------
572
>>> test = np.array([0, 1, 2, 5, 0])
573
>>> states = [0, 2]
574
>>> mask = np.in1d(test, states)
575
>>> mask
576
array([ True, False, True, False, True])
577
>>> test[mask]
578
array([0, 2, 0])
579
>>> mask = np.in1d(test, states, invert=True)
580
>>> mask
581
array([False, True, False, True, False])
582
>>> test[mask]
583
array([1, 5])
584
"""
585
# Ravel both arrays, behavior for the first array could be different
586
ar1 = np.asarray(ar1).ravel()
587
ar2 = np.asarray(ar2).ravel()
588
589
# Ensure that iteration through object arrays yields size-1 arrays
590
if ar2.dtype == object:
591
ar2 = ar2.reshape(-1, 1)
592
593
# Check if one of the arrays may contain arbitrary objects
594
contains_object = ar1.dtype.hasobject or ar2.dtype.hasobject
595
596
# This code is run when
597
# a) the first condition is true, making the code significantly faster
598
# b) the second condition is true (i.e. `ar1` or `ar2` may contain
599
# arbitrary objects), since then sorting is not guaranteed to work
600
if len(ar2) < 10 * len(ar1) ** 0.145 or contains_object:
601
if invert:
602
mask = np.ones(len(ar1), dtype=bool)
603
for a in ar2:
604
mask &= (ar1 != a)
605
else:
606
mask = np.zeros(len(ar1), dtype=bool)
607
for a in ar2:
608
mask |= (ar1 == a)
609
return mask
610
611
# Otherwise use sorting
612
if not assume_unique:
613
ar1, rev_idx = np.unique(ar1, return_inverse=True)
614
ar2 = np.unique(ar2)
615
616
ar = np.concatenate((ar1, ar2))
617
# We need this to be a stable sort, so always use 'mergesort'
618
# here. The values from the first array should always come before
619
# the values from the second array.
620
order = ar.argsort(kind='mergesort')
621
sar = ar[order]
622
if invert:
623
bool_ar = (sar[1:] != sar[:-1])
624
else:
625
bool_ar = (sar[1:] == sar[:-1])
626
flag = np.concatenate((bool_ar, [invert]))
627
ret = np.empty(ar.shape, dtype=bool)
628
ret[order] = flag
629
630
if assume_unique:
631
return ret[:len(ar1)]
632
else:
633
return ret[rev_idx]
634
635
636
def _isin_dispatcher(element, test_elements, assume_unique=None, invert=None):
637
return (element, test_elements)
638
639
640
@array_function_dispatch(_isin_dispatcher)
641
def isin(element, test_elements, assume_unique=False, invert=False):
642
"""
643
Calculates `element in test_elements`, broadcasting over `element` only.
644
Returns a boolean array of the same shape as `element` that is True
645
where an element of `element` is in `test_elements` and False otherwise.
646
647
Parameters
648
----------
649
element : array_like
650
Input array.
651
test_elements : array_like
652
The values against which to test each value of `element`.
653
This argument is flattened if it is an array or array_like.
654
See notes for behavior with non-array-like parameters.
655
assume_unique : bool, optional
656
If True, the input arrays are both assumed to be unique, which
657
can speed up the calculation. Default is False.
658
invert : bool, optional
659
If True, the values in the returned array are inverted, as if
660
calculating `element not in test_elements`. Default is False.
661
``np.isin(a, b, invert=True)`` is equivalent to (but faster
662
than) ``np.invert(np.isin(a, b))``.
663
664
Returns
665
-------
666
isin : ndarray, bool
667
Has the same shape as `element`. The values `element[isin]`
668
are in `test_elements`.
669
670
See Also
671
--------
672
in1d : Flattened version of this function.
673
numpy.lib.arraysetops : Module with a number of other functions for
674
performing set operations on arrays.
675
676
Notes
677
-----
678
679
`isin` is an element-wise function version of the python keyword `in`.
680
``isin(a, b)`` is roughly equivalent to
681
``np.array([item in b for item in a])`` if `a` and `b` are 1-D sequences.
682
683
`element` and `test_elements` are converted to arrays if they are not
684
already. If `test_elements` is a set (or other non-sequence collection)
685
it will be converted to an object array with one element, rather than an
686
array of the values contained in `test_elements`. This is a consequence
687
of the `array` constructor's way of handling non-sequence collections.
688
Converting the set to a list usually gives the desired behavior.
689
690
.. versionadded:: 1.13.0
691
692
Examples
693
--------
694
>>> element = 2*np.arange(4).reshape((2, 2))
695
>>> element
696
array([[0, 2],
697
[4, 6]])
698
>>> test_elements = [1, 2, 4, 8]
699
>>> mask = np.isin(element, test_elements)
700
>>> mask
701
array([[False, True],
702
[ True, False]])
703
>>> element[mask]
704
array([2, 4])
705
706
The indices of the matched values can be obtained with `nonzero`:
707
708
>>> np.nonzero(mask)
709
(array([0, 1]), array([1, 0]))
710
711
The test can also be inverted:
712
713
>>> mask = np.isin(element, test_elements, invert=True)
714
>>> mask
715
array([[ True, False],
716
[False, True]])
717
>>> element[mask]
718
array([0, 6])
719
720
Because of how `array` handles sets, the following does not
721
work as expected:
722
723
>>> test_set = {1, 2, 4, 8}
724
>>> np.isin(element, test_set)
725
array([[False, False],
726
[False, False]])
727
728
Casting the set to a list gives the expected result:
729
730
>>> np.isin(element, list(test_set))
731
array([[False, True],
732
[ True, False]])
733
"""
734
element = np.asarray(element)
735
return in1d(element, test_elements, assume_unique=assume_unique,
736
invert=invert).reshape(element.shape)
737
738
739
def _union1d_dispatcher(ar1, ar2):
740
return (ar1, ar2)
741
742
743
@array_function_dispatch(_union1d_dispatcher)
744
def union1d(ar1, ar2):
745
"""
746
Find the union of two arrays.
747
748
Return the unique, sorted array of values that are in either of the two
749
input arrays.
750
751
Parameters
752
----------
753
ar1, ar2 : array_like
754
Input arrays. They are flattened if they are not already 1D.
755
756
Returns
757
-------
758
union1d : ndarray
759
Unique, sorted union of the input arrays.
760
761
See Also
762
--------
763
numpy.lib.arraysetops : Module with a number of other functions for
764
performing set operations on arrays.
765
766
Examples
767
--------
768
>>> np.union1d([-1, 0, 1], [-2, 0, 2])
769
array([-2, -1, 0, 1, 2])
770
771
To find the union of more than two arrays, use functools.reduce:
772
773
>>> from functools import reduce
774
>>> reduce(np.union1d, ([1, 3, 4, 3], [3, 1, 2, 1], [6, 3, 4, 2]))
775
array([1, 2, 3, 4, 6])
776
"""
777
return unique(np.concatenate((ar1, ar2), axis=None))
778
779
780
def _setdiff1d_dispatcher(ar1, ar2, assume_unique=None):
781
return (ar1, ar2)
782
783
784
@array_function_dispatch(_setdiff1d_dispatcher)
785
def setdiff1d(ar1, ar2, assume_unique=False):
786
"""
787
Find the set difference of two arrays.
788
789
Return the unique values in `ar1` that are not in `ar2`.
790
791
Parameters
792
----------
793
ar1 : array_like
794
Input array.
795
ar2 : array_like
796
Input comparison array.
797
assume_unique : bool
798
If True, the input arrays are both assumed to be unique, which
799
can speed up the calculation. Default is False.
800
801
Returns
802
-------
803
setdiff1d : ndarray
804
1D array of values in `ar1` that are not in `ar2`. The result
805
is sorted when `assume_unique=False`, but otherwise only sorted
806
if the input is sorted.
807
808
See Also
809
--------
810
numpy.lib.arraysetops : Module with a number of other functions for
811
performing set operations on arrays.
812
813
Examples
814
--------
815
>>> a = np.array([1, 2, 3, 2, 4, 1])
816
>>> b = np.array([3, 4, 5, 6])
817
>>> np.setdiff1d(a, b)
818
array([1, 2])
819
820
"""
821
if assume_unique:
822
ar1 = np.asarray(ar1).ravel()
823
else:
824
ar1 = unique(ar1)
825
ar2 = unique(ar2)
826
return ar1[in1d(ar1, ar2, assume_unique=True, invert=True)]
827
828