Coverage for /var/srv/projects/api.amasfac.comuna18.com/tmp/venv/lib/python3.9/site-packages/numpy/lib/arraysetops.py: 12%

198 statements  

« prev     ^ index     » next       coverage.py v6.4.4, created at 2023-07-17 14:22 -0600

1""" 

2Set operations for arrays based on sorting. 

3 

4Notes 

5----- 

6 

7For floating point arrays, inaccurate results may appear due to usual round-off 

8and floating point comparison issues. 

9 

10Speed could be gained in some operations by an implementation of 

11`numpy.sort`, that can provide directly the permutation vectors, thus avoiding 

12calls to `numpy.argsort`. 

13 

14Original author: Robert Cimrman 

15 

16""" 

17import functools 

18 

19import numpy as np 

20from numpy.core import overrides 

21 

22 

23array_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 

33def _ediff1d_dispatcher(ary, to_end=None, to_begin=None): 

34 return (ary, to_end, to_begin) 

35 

36 

37@array_function_dispatch(_ediff1d_dispatcher) 

38def 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 

125def _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 

133def _unique_dispatcher(ar, return_index=None, return_inverse=None, 

134 return_counts=None, axis=None, *, equal_nan=None): 

135 return (ar,) 

136 

137 

138@array_function_dispatch(_unique_dispatcher) 

139def unique(ar, return_index=False, return_inverse=False, 

140 return_counts=False, axis=None, *, equal_nan=True): 

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 axis : int or None, optional 

166 The axis to operate on. If None, `ar` will be flattened. If an integer, 

167 the subarrays indexed by the given axis will be flattened and treated 

168 as the elements of a 1-D array with the dimension of the given axis, 

169 see the notes for more details. Object arrays or structured arrays 

170 that contain objects are not supported if the `axis` kwarg is used. The 

171 default is None. 

172 

173 .. versionadded:: 1.13.0 

174 

175 equal_nan : bool, optional 

176 If True, collapses multiple NaN values in the return array into one. 

177 

178 .. versionadded:: 1.24 

179 

180 Returns 

181 ------- 

182 unique : ndarray 

183 The sorted unique values. 

184 unique_indices : ndarray, optional 

185 The indices of the first occurrences of the unique values in the 

186 original array. Only provided if `return_index` is True. 

187 unique_inverse : ndarray, optional 

188 The indices to reconstruct the original array from the 

189 unique array. Only provided if `return_inverse` is True. 

190 unique_counts : ndarray, optional 

191 The number of times each of the unique values comes up in the 

192 original array. Only provided if `return_counts` is True. 

193 

194 .. versionadded:: 1.9.0 

195 

196 See Also 

197 -------- 

198 numpy.lib.arraysetops : Module with a number of other functions for 

199 performing set operations on arrays. 

200 repeat : Repeat elements of an array. 

201 

202 Notes 

203 ----- 

204 When an axis is specified the subarrays indexed by the axis are sorted. 

205 This is done by making the specified axis the first dimension of the array 

206 (move the axis to the first dimension to keep the order of the other axes) 

207 and then flattening the subarrays in C order. The flattened subarrays are 

208 then viewed as a structured type with each element given a label, with the 

209 effect that we end up with a 1-D array of structured types that can be 

210 treated in the same way as any other 1-D array. The result is that the 

211 flattened subarrays are sorted in lexicographic order starting with the 

212 first element. 

213 

214 .. versionchanged: NumPy 1.21 

215 If nan values are in the input array, a single nan is put 

216 to the end of the sorted unique values. 

217 

218 Also for complex arrays all NaN values are considered equivalent 

219 (no matter whether the NaN is in the real or imaginary part). 

220 As the representant for the returned array the smallest one in the 

221 lexicographical order is chosen - see np.sort for how the lexicographical 

222 order is defined for complex arrays. 

223 

224 Examples 

225 -------- 

226 >>> np.unique([1, 1, 2, 2, 3, 3]) 

227 array([1, 2, 3]) 

228 >>> a = np.array([[1, 1], [2, 3]]) 

229 >>> np.unique(a) 

230 array([1, 2, 3]) 

231 

232 Return the unique rows of a 2D array 

233 

234 >>> a = np.array([[1, 0, 0], [1, 0, 0], [2, 3, 4]]) 

235 >>> np.unique(a, axis=0) 

236 array([[1, 0, 0], [2, 3, 4]]) 

237 

238 Return the indices of the original array that give the unique values: 

239 

240 >>> a = np.array(['a', 'b', 'b', 'c', 'a']) 

241 >>> u, indices = np.unique(a, return_index=True) 

242 >>> u 

243 array(['a', 'b', 'c'], dtype='<U1') 

244 >>> indices 

245 array([0, 1, 3]) 

246 >>> a[indices] 

247 array(['a', 'b', 'c'], dtype='<U1') 

248 

249 Reconstruct the input array from the unique values and inverse: 

250 

251 >>> a = np.array([1, 2, 6, 4, 2, 3, 2]) 

252 >>> u, indices = np.unique(a, return_inverse=True) 

253 >>> u 

254 array([1, 2, 3, 4, 6]) 

255 >>> indices 

256 array([0, 1, 4, 3, 1, 2, 1]) 

257 >>> u[indices] 

258 array([1, 2, 6, 4, 2, 3, 2]) 

259 

260 Reconstruct the input values from the unique values and counts: 

261 

262 >>> a = np.array([1, 2, 6, 4, 2, 3, 2]) 

263 >>> values, counts = np.unique(a, return_counts=True) 

264 >>> values 

265 array([1, 2, 3, 4, 6]) 

266 >>> counts 

267 array([1, 3, 1, 1, 1]) 

268 >>> np.repeat(values, counts) 

269 array([1, 2, 2, 2, 3, 4, 6]) # original order not preserved 

270 

271 """ 

272 ar = np.asanyarray(ar) 

273 if axis is None: 

274 ret = _unique1d(ar, return_index, return_inverse, return_counts, 

275 equal_nan=equal_nan) 

276 return _unpack_tuple(ret) 

277 

278 # axis was specified and not None 

279 try: 

280 ar = np.moveaxis(ar, axis, 0) 

281 except np.AxisError: 

282 # this removes the "axis1" or "axis2" prefix from the error message 

283 raise np.AxisError(axis, ar.ndim) from None 

284 

285 # Must reshape to a contiguous 2D array for this to work... 

286 orig_shape, orig_dtype = ar.shape, ar.dtype 

287 ar = ar.reshape(orig_shape[0], np.prod(orig_shape[1:], dtype=np.intp)) 

288 ar = np.ascontiguousarray(ar) 

289 dtype = [('f{i}'.format(i=i), ar.dtype) for i in range(ar.shape[1])] 

290 

291 # At this point, `ar` has shape `(n, m)`, and `dtype` is a structured 

292 # data type with `m` fields where each field has the data type of `ar`. 

293 # In the following, we create the array `consolidated`, which has 

294 # shape `(n,)` with data type `dtype`. 

295 try: 

296 if ar.shape[1] > 0: 

297 consolidated = ar.view(dtype) 

298 else: 

299 # If ar.shape[1] == 0, then dtype will be `np.dtype([])`, which is 

300 # a data type with itemsize 0, and the call `ar.view(dtype)` will 

301 # fail. Instead, we'll use `np.empty` to explicitly create the 

302 # array with shape `(len(ar),)`. Because `dtype` in this case has 

303 # itemsize 0, the total size of the result is still 0 bytes. 

304 consolidated = np.empty(len(ar), dtype=dtype) 

305 except TypeError as e: 

306 # There's no good way to do this for object arrays, etc... 

307 msg = 'The axis argument to unique is not supported for dtype {dt}' 

308 raise TypeError(msg.format(dt=ar.dtype)) from e 

309 

310 def reshape_uniq(uniq): 

311 n = len(uniq) 

312 uniq = uniq.view(orig_dtype) 

313 uniq = uniq.reshape(n, *orig_shape[1:]) 

314 uniq = np.moveaxis(uniq, 0, axis) 

315 return uniq 

316 

317 output = _unique1d(consolidated, return_index, 

318 return_inverse, return_counts, equal_nan=equal_nan) 

319 output = (reshape_uniq(output[0]),) + output[1:] 

320 return _unpack_tuple(output) 

321 

322 

323def _unique1d(ar, return_index=False, return_inverse=False, 

324 return_counts=False, *, equal_nan=True): 

325 """ 

326 Find the unique elements of an array, ignoring shape. 

327 """ 

328 ar = np.asanyarray(ar).flatten() 

329 

330 optional_indices = return_index or return_inverse 

331 

332 if optional_indices: 

333 perm = ar.argsort(kind='mergesort' if return_index else 'quicksort') 

334 aux = ar[perm] 

335 else: 

336 ar.sort() 

337 aux = ar 

338 mask = np.empty(aux.shape, dtype=np.bool_) 

339 mask[:1] = True 

340 if (equal_nan and aux.shape[0] > 0 and aux.dtype.kind in "cfmM" and 

341 np.isnan(aux[-1])): 

342 if aux.dtype.kind == "c": # for complex all NaNs are considered equivalent 

343 aux_firstnan = np.searchsorted(np.isnan(aux), True, side='left') 

344 else: 

345 aux_firstnan = np.searchsorted(aux, aux[-1], side='left') 

346 if aux_firstnan > 0: 

347 mask[1:aux_firstnan] = ( 

348 aux[1:aux_firstnan] != aux[:aux_firstnan - 1]) 

349 mask[aux_firstnan] = True 

350 mask[aux_firstnan + 1:] = False 

351 else: 

352 mask[1:] = aux[1:] != aux[:-1] 

353 

354 ret = (aux[mask],) 

355 if return_index: 

356 ret += (perm[mask],) 

357 if return_inverse: 

358 imask = np.cumsum(mask) - 1 

359 inv_idx = np.empty(mask.shape, dtype=np.intp) 

360 inv_idx[perm] = imask 

361 ret += (inv_idx,) 

362 if return_counts: 

363 idx = np.concatenate(np.nonzero(mask) + ([mask.size],)) 

364 ret += (np.diff(idx),) 

365 return ret 

366 

367 

368def _intersect1d_dispatcher( 

369 ar1, ar2, assume_unique=None, return_indices=None): 

370 return (ar1, ar2) 

371 

372 

373@array_function_dispatch(_intersect1d_dispatcher) 

374def intersect1d(ar1, ar2, assume_unique=False, return_indices=False): 

375 """ 

376 Find the intersection of two arrays. 

377 

378 Return the sorted, unique values that are in both of the input arrays. 

379 

380 Parameters 

381 ---------- 

382 ar1, ar2 : array_like 

383 Input arrays. Will be flattened if not already 1D. 

384 assume_unique : bool 

385 If True, the input arrays are both assumed to be unique, which 

386 can speed up the calculation. If True but ``ar1`` or ``ar2`` are not 

387 unique, incorrect results and out-of-bounds indices could result. 

388 Default is False. 

389 return_indices : bool 

390 If True, the indices which correspond to the intersection of the two 

391 arrays are returned. The first instance of a value is used if there are 

392 multiple. Default is False. 

393 

394 .. versionadded:: 1.15.0 

395 

396 Returns 

397 ------- 

398 intersect1d : ndarray 

399 Sorted 1D array of common and unique elements. 

400 comm1 : ndarray 

401 The indices of the first occurrences of the common values in `ar1`. 

402 Only provided if `return_indices` is True. 

403 comm2 : ndarray 

404 The indices of the first occurrences of the common values in `ar2`. 

405 Only provided if `return_indices` is True. 

406 

407 

408 See Also 

409 -------- 

410 numpy.lib.arraysetops : Module with a number of other functions for 

411 performing set operations on arrays. 

412 

413 Examples 

414 -------- 

415 >>> np.intersect1d([1, 3, 4, 3], [3, 1, 2, 1]) 

416 array([1, 3]) 

417 

418 To intersect more than two arrays, use functools.reduce: 

419 

420 >>> from functools import reduce 

421 >>> reduce(np.intersect1d, ([1, 3, 4, 3], [3, 1, 2, 1], [6, 3, 4, 2])) 

422 array([3]) 

423 

424 To return the indices of the values common to the input arrays 

425 along with the intersected values: 

426 

427 >>> x = np.array([1, 1, 2, 3, 4]) 

428 >>> y = np.array([2, 1, 4, 6]) 

429 >>> xy, x_ind, y_ind = np.intersect1d(x, y, return_indices=True) 

430 >>> x_ind, y_ind 

431 (array([0, 2, 4]), array([1, 0, 2])) 

432 >>> xy, x[x_ind], y[y_ind] 

433 (array([1, 2, 4]), array([1, 2, 4]), array([1, 2, 4])) 

434 

435 """ 

436 ar1 = np.asanyarray(ar1) 

437 ar2 = np.asanyarray(ar2) 

438 

439 if not assume_unique: 

440 if return_indices: 

441 ar1, ind1 = unique(ar1, return_index=True) 

442 ar2, ind2 = unique(ar2, return_index=True) 

443 else: 

444 ar1 = unique(ar1) 

445 ar2 = unique(ar2) 

446 else: 

447 ar1 = ar1.ravel() 

448 ar2 = ar2.ravel() 

449 

450 aux = np.concatenate((ar1, ar2)) 

451 if return_indices: 

452 aux_sort_indices = np.argsort(aux, kind='mergesort') 

453 aux = aux[aux_sort_indices] 

454 else: 

455 aux.sort() 

456 

457 mask = aux[1:] == aux[:-1] 

458 int1d = aux[:-1][mask] 

459 

460 if return_indices: 

461 ar1_indices = aux_sort_indices[:-1][mask] 

462 ar2_indices = aux_sort_indices[1:][mask] - ar1.size 

463 if not assume_unique: 

464 ar1_indices = ind1[ar1_indices] 

465 ar2_indices = ind2[ar2_indices] 

466 

467 return int1d, ar1_indices, ar2_indices 

468 else: 

469 return int1d 

470 

471 

472def _setxor1d_dispatcher(ar1, ar2, assume_unique=None): 

473 return (ar1, ar2) 

474 

475 

476@array_function_dispatch(_setxor1d_dispatcher) 

477def setxor1d(ar1, ar2, assume_unique=False): 

478 """ 

479 Find the set exclusive-or of two arrays. 

480 

481 Return the sorted, unique values that are in only one (not both) of the 

482 input arrays. 

483 

484 Parameters 

485 ---------- 

486 ar1, ar2 : array_like 

487 Input arrays. 

488 assume_unique : bool 

489 If True, the input arrays are both assumed to be unique, which 

490 can speed up the calculation. Default is False. 

491 

492 Returns 

493 ------- 

494 setxor1d : ndarray 

495 Sorted 1D array of unique values that are in only one of the input 

496 arrays. 

497 

498 Examples 

499 -------- 

500 >>> a = np.array([1, 2, 3, 2, 4]) 

501 >>> b = np.array([2, 3, 5, 7, 5]) 

502 >>> np.setxor1d(a,b) 

503 array([1, 4, 5, 7]) 

504 

505 """ 

506 if not assume_unique: 

507 ar1 = unique(ar1) 

508 ar2 = unique(ar2) 

509 

510 aux = np.concatenate((ar1, ar2)) 

511 if aux.size == 0: 

512 return aux 

513 

514 aux.sort() 

515 flag = np.concatenate(([True], aux[1:] != aux[:-1], [True])) 

516 return aux[flag[1:] & flag[:-1]] 

517 

518 

519def _in1d_dispatcher(ar1, ar2, assume_unique=None, invert=None): 

520 return (ar1, ar2) 

521 

522 

523@array_function_dispatch(_in1d_dispatcher) 

524def in1d(ar1, ar2, assume_unique=False, invert=False): 

525 """ 

526 Test whether each element of a 1-D array is also present in a second array. 

527 

528 Returns a boolean array the same length as `ar1` that is True 

529 where an element of `ar1` is in `ar2` and False otherwise. 

530 

531 We recommend using :func:`isin` instead of `in1d` for new code. 

532 

533 Parameters 

534 ---------- 

535 ar1 : (M,) array_like 

536 Input array. 

537 ar2 : array_like 

538 The values against which to test each value of `ar1`. 

539 assume_unique : bool, optional 

540 If True, the input arrays are both assumed to be unique, which 

541 can speed up the calculation. Default is False. 

542 invert : bool, optional 

543 If True, the values in the returned array are inverted (that is, 

544 False where an element of `ar1` is in `ar2` and True otherwise). 

545 Default is False. ``np.in1d(a, b, invert=True)`` is equivalent 

546 to (but is faster than) ``np.invert(in1d(a, b))``. 

547 

548 .. versionadded:: 1.8.0 

549 

550 Returns 

551 ------- 

552 in1d : (M,) ndarray, bool 

553 The values `ar1[in1d]` are in `ar2`. 

554 

555 See Also 

556 -------- 

557 isin : Version of this function that preserves the 

558 shape of ar1. 

559 numpy.lib.arraysetops : Module with a number of other functions for 

560 performing set operations on arrays. 

561 

562 Notes 

563 ----- 

564 `in1d` can be considered as an element-wise function version of the 

565 python keyword `in`, for 1-D sequences. ``in1d(a, b)`` is roughly 

566 equivalent to ``np.array([item in b for item in a])``. 

567 However, this idea fails if `ar2` is a set, or similar (non-sequence) 

568 container: As ``ar2`` is converted to an array, in those cases 

569 ``asarray(ar2)`` is an object array rather than the expected array of 

570 contained values. 

571 

572 .. versionadded:: 1.4.0 

573 

574 Examples 

575 -------- 

576 >>> test = np.array([0, 1, 2, 5, 0]) 

577 >>> states = [0, 2] 

578 >>> mask = np.in1d(test, states) 

579 >>> mask 

580 array([ True, False, True, False, True]) 

581 >>> test[mask] 

582 array([0, 2, 0]) 

583 >>> mask = np.in1d(test, states, invert=True) 

584 >>> mask 

585 array([False, True, False, True, False]) 

586 >>> test[mask] 

587 array([1, 5]) 

588 """ 

589 # Ravel both arrays, behavior for the first array could be different 

590 ar1 = np.asarray(ar1).ravel() 

591 ar2 = np.asarray(ar2).ravel() 

592 

593 # Ensure that iteration through object arrays yields size-1 arrays 

594 if ar2.dtype == object: 

595 ar2 = ar2.reshape(-1, 1) 

596 

597 # Check if one of the arrays may contain arbitrary objects 

598 contains_object = ar1.dtype.hasobject or ar2.dtype.hasobject 

599 

600 # This code is run when 

601 # a) the first condition is true, making the code significantly faster 

602 # b) the second condition is true (i.e. `ar1` or `ar2` may contain 

603 # arbitrary objects), since then sorting is not guaranteed to work 

604 if len(ar2) < 10 * len(ar1) ** 0.145 or contains_object: 

605 if invert: 

606 mask = np.ones(len(ar1), dtype=bool) 

607 for a in ar2: 

608 mask &= (ar1 != a) 

609 else: 

610 mask = np.zeros(len(ar1), dtype=bool) 

611 for a in ar2: 

612 mask |= (ar1 == a) 

613 return mask 

614 

615 # Otherwise use sorting 

616 if not assume_unique: 

617 ar1, rev_idx = np.unique(ar1, return_inverse=True) 

618 ar2 = np.unique(ar2) 

619 

620 ar = np.concatenate((ar1, ar2)) 

621 # We need this to be a stable sort, so always use 'mergesort' 

622 # here. The values from the first array should always come before 

623 # the values from the second array. 

624 order = ar.argsort(kind='mergesort') 

625 sar = ar[order] 

626 if invert: 

627 bool_ar = (sar[1:] != sar[:-1]) 

628 else: 

629 bool_ar = (sar[1:] == sar[:-1]) 

630 flag = np.concatenate((bool_ar, [invert])) 

631 ret = np.empty(ar.shape, dtype=bool) 

632 ret[order] = flag 

633 

634 if assume_unique: 

635 return ret[:len(ar1)] 

636 else: 

637 return ret[rev_idx] 

638 

639 

640def _isin_dispatcher(element, test_elements, assume_unique=None, invert=None): 

641 return (element, test_elements) 

642 

643 

644@array_function_dispatch(_isin_dispatcher) 

645def isin(element, test_elements, assume_unique=False, invert=False): 

646 """ 

647 Calculates ``element in test_elements``, broadcasting over `element` only. 

648 Returns a boolean array of the same shape as `element` that is True 

649 where an element of `element` is in `test_elements` and False otherwise. 

650 

651 Parameters 

652 ---------- 

653 element : array_like 

654 Input array. 

655 test_elements : array_like 

656 The values against which to test each value of `element`. 

657 This argument is flattened if it is an array or array_like. 

658 See notes for behavior with non-array-like parameters. 

659 assume_unique : bool, optional 

660 If True, the input arrays are both assumed to be unique, which 

661 can speed up the calculation. Default is False. 

662 invert : bool, optional 

663 If True, the values in the returned array are inverted, as if 

664 calculating `element not in test_elements`. Default is False. 

665 ``np.isin(a, b, invert=True)`` is equivalent to (but faster 

666 than) ``np.invert(np.isin(a, b))``. 

667 

668 Returns 

669 ------- 

670 isin : ndarray, bool 

671 Has the same shape as `element`. The values `element[isin]` 

672 are in `test_elements`. 

673 

674 See Also 

675 -------- 

676 in1d : Flattened version of this function. 

677 numpy.lib.arraysetops : Module with a number of other functions for 

678 performing set operations on arrays. 

679 

680 Notes 

681 ----- 

682 

683 `isin` is an element-wise function version of the python keyword `in`. 

684 ``isin(a, b)`` is roughly equivalent to 

685 ``np.array([item in b for item in a])`` if `a` and `b` are 1-D sequences. 

686 

687 `element` and `test_elements` are converted to arrays if they are not 

688 already. If `test_elements` is a set (or other non-sequence collection) 

689 it will be converted to an object array with one element, rather than an 

690 array of the values contained in `test_elements`. This is a consequence 

691 of the `array` constructor's way of handling non-sequence collections. 

692 Converting the set to a list usually gives the desired behavior. 

693 

694 .. versionadded:: 1.13.0 

695 

696 Examples 

697 -------- 

698 >>> element = 2*np.arange(4).reshape((2, 2)) 

699 >>> element 

700 array([[0, 2], 

701 [4, 6]]) 

702 >>> test_elements = [1, 2, 4, 8] 

703 >>> mask = np.isin(element, test_elements) 

704 >>> mask 

705 array([[False, True], 

706 [ True, False]]) 

707 >>> element[mask] 

708 array([2, 4]) 

709 

710 The indices of the matched values can be obtained with `nonzero`: 

711 

712 >>> np.nonzero(mask) 

713 (array([0, 1]), array([1, 0])) 

714 

715 The test can also be inverted: 

716 

717 >>> mask = np.isin(element, test_elements, invert=True) 

718 >>> mask 

719 array([[ True, False], 

720 [False, True]]) 

721 >>> element[mask] 

722 array([0, 6]) 

723 

724 Because of how `array` handles sets, the following does not 

725 work as expected: 

726 

727 >>> test_set = {1, 2, 4, 8} 

728 >>> np.isin(element, test_set) 

729 array([[False, False], 

730 [False, False]]) 

731 

732 Casting the set to a list gives the expected result: 

733 

734 >>> np.isin(element, list(test_set)) 

735 array([[False, True], 

736 [ True, False]]) 

737 """ 

738 element = np.asarray(element) 

739 return in1d(element, test_elements, assume_unique=assume_unique, 

740 invert=invert).reshape(element.shape) 

741 

742 

743def _union1d_dispatcher(ar1, ar2): 

744 return (ar1, ar2) 

745 

746 

747@array_function_dispatch(_union1d_dispatcher) 

748def union1d(ar1, ar2): 

749 """ 

750 Find the union of two arrays. 

751 

752 Return the unique, sorted array of values that are in either of the two 

753 input arrays. 

754 

755 Parameters 

756 ---------- 

757 ar1, ar2 : array_like 

758 Input arrays. They are flattened if they are not already 1D. 

759 

760 Returns 

761 ------- 

762 union1d : ndarray 

763 Unique, sorted union of the input arrays. 

764 

765 See Also 

766 -------- 

767 numpy.lib.arraysetops : Module with a number of other functions for 

768 performing set operations on arrays. 

769 

770 Examples 

771 -------- 

772 >>> np.union1d([-1, 0, 1], [-2, 0, 2]) 

773 array([-2, -1, 0, 1, 2]) 

774 

775 To find the union of more than two arrays, use functools.reduce: 

776 

777 >>> from functools import reduce 

778 >>> reduce(np.union1d, ([1, 3, 4, 3], [3, 1, 2, 1], [6, 3, 4, 2])) 

779 array([1, 2, 3, 4, 6]) 

780 """ 

781 return unique(np.concatenate((ar1, ar2), axis=None)) 

782 

783 

784def _setdiff1d_dispatcher(ar1, ar2, assume_unique=None): 

785 return (ar1, ar2) 

786 

787 

788@array_function_dispatch(_setdiff1d_dispatcher) 

789def setdiff1d(ar1, ar2, assume_unique=False): 

790 """ 

791 Find the set difference of two arrays. 

792 

793 Return the unique values in `ar1` that are not in `ar2`. 

794 

795 Parameters 

796 ---------- 

797 ar1 : array_like 

798 Input array. 

799 ar2 : array_like 

800 Input comparison array. 

801 assume_unique : bool 

802 If True, the input arrays are both assumed to be unique, which 

803 can speed up the calculation. Default is False. 

804 

805 Returns 

806 ------- 

807 setdiff1d : ndarray 

808 1D array of values in `ar1` that are not in `ar2`. The result 

809 is sorted when `assume_unique=False`, but otherwise only sorted 

810 if the input is sorted. 

811 

812 See Also 

813 -------- 

814 numpy.lib.arraysetops : Module with a number of other functions for 

815 performing set operations on arrays. 

816 

817 Examples 

818 -------- 

819 >>> a = np.array([1, 2, 3, 2, 4, 1]) 

820 >>> b = np.array([3, 4, 5, 6]) 

821 >>> np.setdiff1d(a, b) 

822 array([1, 2]) 

823 

824 """ 

825 if assume_unique: 

826 ar1 = np.asarray(ar1).ravel() 

827 else: 

828 ar1 = unique(ar1) 

829 ar2 = unique(ar2) 

830 return ar1[in1d(ar1, ar2, assume_unique=True, invert=True)]