Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.10/site-packages/numpy/lib/_twodim_base_impl.py: 31%

Shortcuts on this page

r m x   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

175 statements  

1""" Basic functions for manipulating 2d arrays 

2 

3""" 

4import functools 

5import operator 

6 

7from numpy._core._multiarray_umath import _array_converter 

8from numpy._core.numeric import ( 

9 asanyarray, arange, zeros, greater_equal, multiply, ones, 

10 asarray, where, int8, int16, int32, int64, intp, empty, promote_types, 

11 diagonal, nonzero, indices 

12 ) 

13from numpy._core.overrides import finalize_array_function_like, set_module 

14from numpy._core import overrides 

15from numpy._core import iinfo 

16from numpy.lib._stride_tricks_impl import broadcast_to 

17 

18 

19__all__ = [ 

20 'diag', 'diagflat', 'eye', 'fliplr', 'flipud', 'tri', 'triu', 

21 'tril', 'vander', 'histogram2d', 'mask_indices', 'tril_indices', 

22 'tril_indices_from', 'triu_indices', 'triu_indices_from', ] 

23 

24 

25array_function_dispatch = functools.partial( 

26 overrides.array_function_dispatch, module='numpy') 

27 

28 

29i1 = iinfo(int8) 

30i2 = iinfo(int16) 

31i4 = iinfo(int32) 

32 

33 

34def _min_int(low, high): 

35 """ get small int that fits the range """ 

36 if high <= i1.max and low >= i1.min: 

37 return int8 

38 if high <= i2.max and low >= i2.min: 

39 return int16 

40 if high <= i4.max and low >= i4.min: 

41 return int32 

42 return int64 

43 

44 

45def _flip_dispatcher(m): 

46 return (m,) 

47 

48 

49@array_function_dispatch(_flip_dispatcher) 

50def fliplr(m): 

51 """ 

52 Reverse the order of elements along axis 1 (left/right). 

53 

54 For a 2-D array, this flips the entries in each row in the left/right 

55 direction. Columns are preserved, but appear in a different order than 

56 before. 

57 

58 Parameters 

59 ---------- 

60 m : array_like 

61 Input array, must be at least 2-D. 

62 

63 Returns 

64 ------- 

65 f : ndarray 

66 A view of `m` with the columns reversed. Since a view 

67 is returned, this operation is :math:`\\mathcal O(1)`. 

68 

69 See Also 

70 -------- 

71 flipud : Flip array in the up/down direction. 

72 flip : Flip array in one or more dimensions. 

73 rot90 : Rotate array counterclockwise. 

74 

75 Notes 

76 ----- 

77 Equivalent to ``m[:,::-1]`` or ``np.flip(m, axis=1)``. 

78 Requires the array to be at least 2-D. 

79 

80 Examples 

81 -------- 

82 >>> import numpy as np 

83 >>> A = np.diag([1.,2.,3.]) 

84 >>> A 

85 array([[1., 0., 0.], 

86 [0., 2., 0.], 

87 [0., 0., 3.]]) 

88 >>> np.fliplr(A) 

89 array([[0., 0., 1.], 

90 [0., 2., 0.], 

91 [3., 0., 0.]]) 

92 

93 >>> rng = np.random.default_rng() 

94 >>> A = rng.normal(size=(2,3,5)) 

95 >>> np.all(np.fliplr(A) == A[:,::-1,...]) 

96 True 

97 

98 """ 

99 m = asanyarray(m) 

100 if m.ndim < 2: 

101 raise ValueError("Input must be >= 2-d.") 

102 return m[:, ::-1] 

103 

104 

105@array_function_dispatch(_flip_dispatcher) 

106def flipud(m): 

107 """ 

108 Reverse the order of elements along axis 0 (up/down). 

109 

110 For a 2-D array, this flips the entries in each column in the up/down 

111 direction. Rows are preserved, but appear in a different order than before. 

112 

113 Parameters 

114 ---------- 

115 m : array_like 

116 Input array. 

117 

118 Returns 

119 ------- 

120 out : array_like 

121 A view of `m` with the rows reversed. Since a view is 

122 returned, this operation is :math:`\\mathcal O(1)`. 

123 

124 See Also 

125 -------- 

126 fliplr : Flip array in the left/right direction. 

127 flip : Flip array in one or more dimensions. 

128 rot90 : Rotate array counterclockwise. 

129 

130 Notes 

131 ----- 

132 Equivalent to ``m[::-1, ...]`` or ``np.flip(m, axis=0)``. 

133 Requires the array to be at least 1-D. 

134 

135 Examples 

136 -------- 

137 >>> import numpy as np 

138 >>> A = np.diag([1.0, 2, 3]) 

139 >>> A 

140 array([[1., 0., 0.], 

141 [0., 2., 0.], 

142 [0., 0., 3.]]) 

143 >>> np.flipud(A) 

144 array([[0., 0., 3.], 

145 [0., 2., 0.], 

146 [1., 0., 0.]]) 

147 

148 >>> rng = np.random.default_rng() 

149 >>> A = rng.normal(size=(2,3,5)) 

150 >>> np.all(np.flipud(A) == A[::-1,...]) 

151 True 

152 

153 >>> np.flipud([1,2]) 

154 array([2, 1]) 

155 

156 """ 

157 m = asanyarray(m) 

158 if m.ndim < 1: 

159 raise ValueError("Input must be >= 1-d.") 

160 return m[::-1, ...] 

161 

162 

163@finalize_array_function_like 

164@set_module('numpy') 

165def eye(N, M=None, k=0, dtype=float, order='C', *, device=None, like=None): 

166 """ 

167 Return a 2-D array with ones on the diagonal and zeros elsewhere. 

168 

169 Parameters 

170 ---------- 

171 N : int 

172 Number of rows in the output. 

173 M : int, optional 

174 Number of columns in the output. If None, defaults to `N`. 

175 k : int, optional 

176 Index of the diagonal: 0 (the default) refers to the main diagonal, 

177 a positive value refers to an upper diagonal, and a negative value 

178 to a lower diagonal. 

179 dtype : data-type, optional 

180 Data-type of the returned array. 

181 order : {'C', 'F'}, optional 

182 Whether the output should be stored in row-major (C-style) or 

183 column-major (Fortran-style) order in memory. 

184 device : str, optional 

185 The device on which to place the created array. Default: None. 

186 For Array-API interoperability only, so must be ``"cpu"`` if passed. 

187 

188 .. versionadded:: 2.0.0 

189 ${ARRAY_FUNCTION_LIKE} 

190 

191 .. versionadded:: 1.20.0 

192 

193 Returns 

194 ------- 

195 I : ndarray of shape (N,M) 

196 An array where all elements are equal to zero, except for the `k`-th 

197 diagonal, whose values are equal to one. 

198 

199 See Also 

200 -------- 

201 identity : (almost) equivalent function 

202 diag : diagonal 2-D array from a 1-D array specified by the user. 

203 

204 Examples 

205 -------- 

206 >>> import numpy as np 

207 >>> np.eye(2, dtype=int) 

208 array([[1, 0], 

209 [0, 1]]) 

210 >>> np.eye(3, k=1) 

211 array([[0., 1., 0.], 

212 [0., 0., 1.], 

213 [0., 0., 0.]]) 

214 

215 """ 

216 if like is not None: 

217 return _eye_with_like( 

218 like, N, M=M, k=k, dtype=dtype, order=order, device=device 

219 ) 

220 if M is None: 

221 M = N 

222 m = zeros((N, M), dtype=dtype, order=order, device=device) 

223 if k >= M: 

224 return m 

225 # Ensure M and k are integers, so we don't get any surprise casting 

226 # results in the expressions `M-k` and `M+1` used below. This avoids 

227 # a problem with inputs with type (for example) np.uint64. 

228 M = operator.index(M) 

229 k = operator.index(k) 

230 if k >= 0: 

231 i = k 

232 else: 

233 i = (-k) * M 

234 m[:M-k].flat[i::M+1] = 1 

235 return m 

236 

237 

238_eye_with_like = array_function_dispatch()(eye) 

239 

240 

241def _diag_dispatcher(v, k=None): 

242 return (v,) 

243 

244 

245@array_function_dispatch(_diag_dispatcher) 

246def diag(v, k=0): 

247 """ 

248 Extract a diagonal or construct a diagonal array. 

249 

250 See the more detailed documentation for ``numpy.diagonal`` if you use this 

251 function to extract a diagonal and wish to write to the resulting array; 

252 whether it returns a copy or a view depends on what version of numpy you 

253 are using. 

254 

255 Parameters 

256 ---------- 

257 v : array_like 

258 If `v` is a 2-D array, return a copy of its `k`-th diagonal. 

259 If `v` is a 1-D array, return a 2-D array with `v` on the `k`-th 

260 diagonal. 

261 k : int, optional 

262 Diagonal in question. The default is 0. Use `k>0` for diagonals 

263 above the main diagonal, and `k<0` for diagonals below the main 

264 diagonal. 

265 

266 Returns 

267 ------- 

268 out : ndarray 

269 The extracted diagonal or constructed diagonal array. 

270 

271 See Also 

272 -------- 

273 diagonal : Return specified diagonals. 

274 diagflat : Create a 2-D array with the flattened input as a diagonal. 

275 trace : Sum along diagonals. 

276 triu : Upper triangle of an array. 

277 tril : Lower triangle of an array. 

278 

279 Examples 

280 -------- 

281 >>> import numpy as np 

282 >>> x = np.arange(9).reshape((3,3)) 

283 >>> x 

284 array([[0, 1, 2], 

285 [3, 4, 5], 

286 [6, 7, 8]]) 

287 

288 >>> np.diag(x) 

289 array([0, 4, 8]) 

290 >>> np.diag(x, k=1) 

291 array([1, 5]) 

292 >>> np.diag(x, k=-1) 

293 array([3, 7]) 

294 

295 >>> np.diag(np.diag(x)) 

296 array([[0, 0, 0], 

297 [0, 4, 0], 

298 [0, 0, 8]]) 

299 

300 """ 

301 v = asanyarray(v) 

302 s = v.shape 

303 if len(s) == 1: 

304 n = s[0]+abs(k) 

305 res = zeros((n, n), v.dtype) 

306 if k >= 0: 

307 i = k 

308 else: 

309 i = (-k) * n 

310 res[:n-k].flat[i::n+1] = v 

311 return res 

312 elif len(s) == 2: 

313 return diagonal(v, k) 

314 else: 

315 raise ValueError("Input must be 1- or 2-d.") 

316 

317 

318@array_function_dispatch(_diag_dispatcher) 

319def diagflat(v, k=0): 

320 """ 

321 Create a two-dimensional array with the flattened input as a diagonal. 

322 

323 Parameters 

324 ---------- 

325 v : array_like 

326 Input data, which is flattened and set as the `k`-th 

327 diagonal of the output. 

328 k : int, optional 

329 Diagonal to set; 0, the default, corresponds to the "main" diagonal, 

330 a positive (negative) `k` giving the number of the diagonal above 

331 (below) the main. 

332 

333 Returns 

334 ------- 

335 out : ndarray 

336 The 2-D output array. 

337 

338 See Also 

339 -------- 

340 diag : MATLAB work-alike for 1-D and 2-D arrays. 

341 diagonal : Return specified diagonals. 

342 trace : Sum along diagonals. 

343 

344 Examples 

345 -------- 

346 >>> import numpy as np 

347 >>> np.diagflat([[1,2], [3,4]]) 

348 array([[1, 0, 0, 0], 

349 [0, 2, 0, 0], 

350 [0, 0, 3, 0], 

351 [0, 0, 0, 4]]) 

352 

353 >>> np.diagflat([1,2], 1) 

354 array([[0, 1, 0], 

355 [0, 0, 2], 

356 [0, 0, 0]]) 

357 

358 """ 

359 conv = _array_converter(v) 

360 v, = conv.as_arrays(subok=False) 

361 v = v.ravel() 

362 s = len(v) 

363 n = s + abs(k) 

364 res = zeros((n, n), v.dtype) 

365 if (k >= 0): 

366 i = arange(0, n-k, dtype=intp) 

367 fi = i+k+i*n 

368 else: 

369 i = arange(0, n+k, dtype=intp) 

370 fi = i+(i-k)*n 

371 res.flat[fi] = v 

372 

373 return conv.wrap(res) 

374 

375 

376@finalize_array_function_like 

377@set_module('numpy') 

378def tri(N, M=None, k=0, dtype=float, *, like=None): 

379 """ 

380 An array with ones at and below the given diagonal and zeros elsewhere. 

381 

382 Parameters 

383 ---------- 

384 N : int 

385 Number of rows in the array. 

386 M : int, optional 

387 Number of columns in the array. 

388 By default, `M` is taken equal to `N`. 

389 k : int, optional 

390 The sub-diagonal at and below which the array is filled. 

391 `k` = 0 is the main diagonal, while `k` < 0 is below it, 

392 and `k` > 0 is above. The default is 0. 

393 dtype : dtype, optional 

394 Data type of the returned array. The default is float. 

395 ${ARRAY_FUNCTION_LIKE} 

396 

397 .. versionadded:: 1.20.0 

398 

399 Returns 

400 ------- 

401 tri : ndarray of shape (N, M) 

402 Array with its lower triangle filled with ones and zero elsewhere; 

403 in other words ``T[i,j] == 1`` for ``j <= i + k``, 0 otherwise. 

404 

405 Examples 

406 -------- 

407 >>> import numpy as np 

408 >>> np.tri(3, 5, 2, dtype=int) 

409 array([[1, 1, 1, 0, 0], 

410 [1, 1, 1, 1, 0], 

411 [1, 1, 1, 1, 1]]) 

412 

413 >>> np.tri(3, 5, -1) 

414 array([[0., 0., 0., 0., 0.], 

415 [1., 0., 0., 0., 0.], 

416 [1., 1., 0., 0., 0.]]) 

417 

418 """ 

419 if like is not None: 

420 return _tri_with_like(like, N, M=M, k=k, dtype=dtype) 

421 

422 if M is None: 

423 M = N 

424 

425 m = greater_equal.outer(arange(N, dtype=_min_int(0, N)), 

426 arange(-k, M-k, dtype=_min_int(-k, M - k))) 

427 

428 # Avoid making a copy if the requested type is already bool 

429 m = m.astype(dtype, copy=False) 

430 

431 return m 

432 

433 

434_tri_with_like = array_function_dispatch()(tri) 

435 

436 

437def _trilu_dispatcher(m, k=None): 

438 return (m,) 

439 

440 

441@array_function_dispatch(_trilu_dispatcher) 

442def tril(m, k=0): 

443 """ 

444 Lower triangle of an array. 

445 

446 Return a copy of an array with elements above the `k`-th diagonal zeroed. 

447 For arrays with ``ndim`` exceeding 2, `tril` will apply to the final two 

448 axes. 

449 

450 Parameters 

451 ---------- 

452 m : array_like, shape (..., M, N) 

453 Input array. 

454 k : int, optional 

455 Diagonal above which to zero elements. `k = 0` (the default) is the 

456 main diagonal, `k < 0` is below it and `k > 0` is above. 

457 

458 Returns 

459 ------- 

460 tril : ndarray, shape (..., M, N) 

461 Lower triangle of `m`, of same shape and data-type as `m`. 

462 

463 See Also 

464 -------- 

465 triu : same thing, only for the upper triangle 

466 

467 Examples 

468 -------- 

469 >>> import numpy as np 

470 >>> np.tril([[1,2,3],[4,5,6],[7,8,9],[10,11,12]], -1) 

471 array([[ 0, 0, 0], 

472 [ 4, 0, 0], 

473 [ 7, 8, 0], 

474 [10, 11, 12]]) 

475 

476 >>> np.tril(np.arange(3*4*5).reshape(3, 4, 5)) 

477 array([[[ 0, 0, 0, 0, 0], 

478 [ 5, 6, 0, 0, 0], 

479 [10, 11, 12, 0, 0], 

480 [15, 16, 17, 18, 0]], 

481 [[20, 0, 0, 0, 0], 

482 [25, 26, 0, 0, 0], 

483 [30, 31, 32, 0, 0], 

484 [35, 36, 37, 38, 0]], 

485 [[40, 0, 0, 0, 0], 

486 [45, 46, 0, 0, 0], 

487 [50, 51, 52, 0, 0], 

488 [55, 56, 57, 58, 0]]]) 

489 

490 """ 

491 m = asanyarray(m) 

492 mask = tri(*m.shape[-2:], k=k, dtype=bool) 

493 

494 return where(mask, m, zeros(1, m.dtype)) 

495 

496 

497@array_function_dispatch(_trilu_dispatcher) 

498def triu(m, k=0): 

499 """ 

500 Upper triangle of an array. 

501 

502 Return a copy of an array with the elements below the `k`-th diagonal 

503 zeroed. For arrays with ``ndim`` exceeding 2, `triu` will apply to the 

504 final two axes. 

505 

506 Please refer to the documentation for `tril` for further details. 

507 

508 See Also 

509 -------- 

510 tril : lower triangle of an array 

511 

512 Examples 

513 -------- 

514 >>> import numpy as np 

515 >>> np.triu([[1,2,3],[4,5,6],[7,8,9],[10,11,12]], -1) 

516 array([[ 1, 2, 3], 

517 [ 4, 5, 6], 

518 [ 0, 8, 9], 

519 [ 0, 0, 12]]) 

520 

521 >>> np.triu(np.arange(3*4*5).reshape(3, 4, 5)) 

522 array([[[ 0, 1, 2, 3, 4], 

523 [ 0, 6, 7, 8, 9], 

524 [ 0, 0, 12, 13, 14], 

525 [ 0, 0, 0, 18, 19]], 

526 [[20, 21, 22, 23, 24], 

527 [ 0, 26, 27, 28, 29], 

528 [ 0, 0, 32, 33, 34], 

529 [ 0, 0, 0, 38, 39]], 

530 [[40, 41, 42, 43, 44], 

531 [ 0, 46, 47, 48, 49], 

532 [ 0, 0, 52, 53, 54], 

533 [ 0, 0, 0, 58, 59]]]) 

534 

535 """ 

536 m = asanyarray(m) 

537 mask = tri(*m.shape[-2:], k=k-1, dtype=bool) 

538 

539 return where(mask, zeros(1, m.dtype), m) 

540 

541 

542def _vander_dispatcher(x, N=None, increasing=None): 

543 return (x,) 

544 

545 

546# Originally borrowed from John Hunter and matplotlib 

547@array_function_dispatch(_vander_dispatcher) 

548def vander(x, N=None, increasing=False): 

549 """ 

550 Generate a Vandermonde matrix. 

551 

552 The columns of the output matrix are powers of the input vector. The 

553 order of the powers is determined by the `increasing` boolean argument. 

554 Specifically, when `increasing` is False, the `i`-th output column is 

555 the input vector raised element-wise to the power of ``N - i - 1``. Such 

556 a matrix with a geometric progression in each row is named for Alexandre- 

557 Theophile Vandermonde. 

558 

559 Parameters 

560 ---------- 

561 x : array_like 

562 1-D input array. 

563 N : int, optional 

564 Number of columns in the output. If `N` is not specified, a square 

565 array is returned (``N = len(x)``). 

566 increasing : bool, optional 

567 Order of the powers of the columns. If True, the powers increase 

568 from left to right, if False (the default) they are reversed. 

569 

570 Returns 

571 ------- 

572 out : ndarray 

573 Vandermonde matrix. If `increasing` is False, the first column is 

574 ``x^(N-1)``, the second ``x^(N-2)`` and so forth. If `increasing` is 

575 True, the columns are ``x^0, x^1, ..., x^(N-1)``. 

576 

577 See Also 

578 -------- 

579 polynomial.polynomial.polyvander 

580 

581 Examples 

582 -------- 

583 >>> import numpy as np 

584 >>> x = np.array([1, 2, 3, 5]) 

585 >>> N = 3 

586 >>> np.vander(x, N) 

587 array([[ 1, 1, 1], 

588 [ 4, 2, 1], 

589 [ 9, 3, 1], 

590 [25, 5, 1]]) 

591 

592 >>> np.column_stack([x**(N-1-i) for i in range(N)]) 

593 array([[ 1, 1, 1], 

594 [ 4, 2, 1], 

595 [ 9, 3, 1], 

596 [25, 5, 1]]) 

597 

598 >>> x = np.array([1, 2, 3, 5]) 

599 >>> np.vander(x) 

600 array([[ 1, 1, 1, 1], 

601 [ 8, 4, 2, 1], 

602 [ 27, 9, 3, 1], 

603 [125, 25, 5, 1]]) 

604 >>> np.vander(x, increasing=True) 

605 array([[ 1, 1, 1, 1], 

606 [ 1, 2, 4, 8], 

607 [ 1, 3, 9, 27], 

608 [ 1, 5, 25, 125]]) 

609 

610 The determinant of a square Vandermonde matrix is the product 

611 of the differences between the values of the input vector: 

612 

613 >>> np.linalg.det(np.vander(x)) 

614 48.000000000000043 # may vary 

615 >>> (5-3)*(5-2)*(5-1)*(3-2)*(3-1)*(2-1) 

616 48 

617 

618 """ 

619 x = asarray(x) 

620 if x.ndim != 1: 

621 raise ValueError("x must be a one-dimensional array or sequence.") 

622 if N is None: 

623 N = len(x) 

624 

625 v = empty((len(x), N), dtype=promote_types(x.dtype, int)) 

626 tmp = v[:, ::-1] if not increasing else v 

627 

628 if N > 0: 

629 tmp[:, 0] = 1 

630 if N > 1: 

631 tmp[:, 1:] = x[:, None] 

632 multiply.accumulate(tmp[:, 1:], out=tmp[:, 1:], axis=1) 

633 

634 return v 

635 

636 

637def _histogram2d_dispatcher(x, y, bins=None, range=None, density=None, 

638 weights=None): 

639 yield x 

640 yield y 

641 

642 # This terrible logic is adapted from the checks in histogram2d 

643 try: 

644 N = len(bins) 

645 except TypeError: 

646 N = 1 

647 if N == 2: 

648 yield from bins # bins=[x, y] 

649 else: 

650 yield bins 

651 

652 yield weights 

653 

654 

655@array_function_dispatch(_histogram2d_dispatcher) 

656def histogram2d(x, y, bins=10, range=None, density=None, weights=None): 

657 """ 

658 Compute the bi-dimensional histogram of two data samples. 

659 

660 Parameters 

661 ---------- 

662 x : array_like, shape (N,) 

663 An array containing the x coordinates of the points to be 

664 histogrammed. 

665 y : array_like, shape (N,) 

666 An array containing the y coordinates of the points to be 

667 histogrammed. 

668 bins : int or array_like or [int, int] or [array, array], optional 

669 The bin specification: 

670 

671 * If int, the number of bins for the two dimensions (nx=ny=bins). 

672 * If array_like, the bin edges for the two dimensions 

673 (x_edges=y_edges=bins). 

674 * If [int, int], the number of bins in each dimension 

675 (nx, ny = bins). 

676 * If [array, array], the bin edges in each dimension 

677 (x_edges, y_edges = bins). 

678 * A combination [int, array] or [array, int], where int 

679 is the number of bins and array is the bin edges. 

680 

681 range : array_like, shape(2,2), optional 

682 The leftmost and rightmost edges of the bins along each dimension 

683 (if not specified explicitly in the `bins` parameters): 

684 ``[[xmin, xmax], [ymin, ymax]]``. All values outside of this range 

685 will be considered outliers and not tallied in the histogram. 

686 density : bool, optional 

687 If False, the default, returns the number of samples in each bin. 

688 If True, returns the probability *density* function at the bin, 

689 ``bin_count / sample_count / bin_area``. 

690 weights : array_like, shape(N,), optional 

691 An array of values ``w_i`` weighing each sample ``(x_i, y_i)``. 

692 Weights are normalized to 1 if `density` is True. If `density` is 

693 False, the values of the returned histogram are equal to the sum of 

694 the weights belonging to the samples falling into each bin. 

695 

696 Returns 

697 ------- 

698 H : ndarray, shape(nx, ny) 

699 The bi-dimensional histogram of samples `x` and `y`. Values in `x` 

700 are histogrammed along the first dimension and values in `y` are 

701 histogrammed along the second dimension. 

702 xedges : ndarray, shape(nx+1,) 

703 The bin edges along the first dimension. 

704 yedges : ndarray, shape(ny+1,) 

705 The bin edges along the second dimension. 

706 

707 See Also 

708 -------- 

709 histogram : 1D histogram 

710 histogramdd : Multidimensional histogram 

711 

712 Notes 

713 ----- 

714 When `density` is True, then the returned histogram is the sample 

715 density, defined such that the sum over bins of the product 

716 ``bin_value * bin_area`` is 1. 

717 

718 Please note that the histogram does not follow the Cartesian convention 

719 where `x` values are on the abscissa and `y` values on the ordinate 

720 axis. Rather, `x` is histogrammed along the first dimension of the 

721 array (vertical), and `y` along the second dimension of the array 

722 (horizontal). This ensures compatibility with `histogramdd`. 

723 

724 Examples 

725 -------- 

726 >>> import numpy as np 

727 >>> from matplotlib.image import NonUniformImage 

728 >>> import matplotlib.pyplot as plt 

729 

730 Construct a 2-D histogram with variable bin width. First define the bin 

731 edges: 

732 

733 >>> xedges = [0, 1, 3, 5] 

734 >>> yedges = [0, 2, 3, 4, 6] 

735 

736 Next we create a histogram H with random bin content: 

737 

738 >>> x = np.random.normal(2, 1, 100) 

739 >>> y = np.random.normal(1, 1, 100) 

740 >>> H, xedges, yedges = np.histogram2d(x, y, bins=(xedges, yedges)) 

741 >>> # Histogram does not follow Cartesian convention (see Notes), 

742 >>> # therefore transpose H for visualization purposes. 

743 >>> H = H.T 

744 

745 :func:`imshow <matplotlib.pyplot.imshow>` can only display square bins: 

746 

747 >>> fig = plt.figure(figsize=(7, 3)) 

748 >>> ax = fig.add_subplot(131, title='imshow: square bins') 

749 >>> plt.imshow(H, interpolation='nearest', origin='lower', 

750 ... extent=[xedges[0], xedges[-1], yedges[0], yedges[-1]]) 

751 <matplotlib.image.AxesImage object at 0x...> 

752 

753 :func:`pcolormesh <matplotlib.pyplot.pcolormesh>` can display actual edges: 

754 

755 >>> ax = fig.add_subplot(132, title='pcolormesh: actual edges', 

756 ... aspect='equal') 

757 >>> X, Y = np.meshgrid(xedges, yedges) 

758 >>> ax.pcolormesh(X, Y, H) 

759 <matplotlib.collections.QuadMesh object at 0x...> 

760 

761 :class:`NonUniformImage <matplotlib.image.NonUniformImage>` can be used to 

762 display actual bin edges with interpolation: 

763 

764 >>> ax = fig.add_subplot(133, title='NonUniformImage: interpolated', 

765 ... aspect='equal', xlim=xedges[[0, -1]], ylim=yedges[[0, -1]]) 

766 >>> im = NonUniformImage(ax, interpolation='bilinear') 

767 >>> xcenters = (xedges[:-1] + xedges[1:]) / 2 

768 >>> ycenters = (yedges[:-1] + yedges[1:]) / 2 

769 >>> im.set_data(xcenters, ycenters, H) 

770 >>> ax.add_image(im) 

771 >>> plt.show() 

772 

773 It is also possible to construct a 2-D histogram without specifying bin 

774 edges: 

775 

776 >>> # Generate non-symmetric test data 

777 >>> n = 10000 

778 >>> x = np.linspace(1, 100, n) 

779 >>> y = 2*np.log(x) + np.random.rand(n) - 0.5 

780 >>> # Compute 2d histogram. Note the order of x/y and xedges/yedges 

781 >>> H, yedges, xedges = np.histogram2d(y, x, bins=20) 

782 

783 Now we can plot the histogram using 

784 :func:`pcolormesh <matplotlib.pyplot.pcolormesh>`, and a 

785 :func:`hexbin <matplotlib.pyplot.hexbin>` for comparison. 

786 

787 >>> # Plot histogram using pcolormesh 

788 >>> fig, (ax1, ax2) = plt.subplots(ncols=2, sharey=True) 

789 >>> ax1.pcolormesh(xedges, yedges, H, cmap='rainbow') 

790 >>> ax1.plot(x, 2*np.log(x), 'k-') 

791 >>> ax1.set_xlim(x.min(), x.max()) 

792 >>> ax1.set_ylim(y.min(), y.max()) 

793 >>> ax1.set_xlabel('x') 

794 >>> ax1.set_ylabel('y') 

795 >>> ax1.set_title('histogram2d') 

796 >>> ax1.grid() 

797 

798 >>> # Create hexbin plot for comparison 

799 >>> ax2.hexbin(x, y, gridsize=20, cmap='rainbow') 

800 >>> ax2.plot(x, 2*np.log(x), 'k-') 

801 >>> ax2.set_title('hexbin') 

802 >>> ax2.set_xlim(x.min(), x.max()) 

803 >>> ax2.set_xlabel('x') 

804 >>> ax2.grid() 

805 

806 >>> plt.show() 

807 """ 

808 from numpy import histogramdd 

809 

810 if len(x) != len(y): 

811 raise ValueError('x and y must have the same length.') 

812 

813 try: 

814 N = len(bins) 

815 except TypeError: 

816 N = 1 

817 

818 if N != 1 and N != 2: 

819 xedges = yedges = asarray(bins) 

820 bins = [xedges, yedges] 

821 hist, edges = histogramdd([x, y], bins, range, density, weights) 

822 return hist, edges[0], edges[1] 

823 

824 

825@set_module('numpy') 

826def mask_indices(n, mask_func, k=0): 

827 """ 

828 Return the indices to access (n, n) arrays, given a masking function. 

829 

830 Assume `mask_func` is a function that, for a square array a of size 

831 ``(n, n)`` with a possible offset argument `k`, when called as 

832 ``mask_func(a, k)`` returns a new array with zeros in certain locations 

833 (functions like `triu` or `tril` do precisely this). Then this function 

834 returns the indices where the non-zero values would be located. 

835 

836 Parameters 

837 ---------- 

838 n : int 

839 The returned indices will be valid to access arrays of shape (n, n). 

840 mask_func : callable 

841 A function whose call signature is similar to that of `triu`, `tril`. 

842 That is, ``mask_func(x, k)`` returns a boolean array, shaped like `x`. 

843 `k` is an optional argument to the function. 

844 k : scalar 

845 An optional argument which is passed through to `mask_func`. Functions 

846 like `triu`, `tril` take a second argument that is interpreted as an 

847 offset. 

848 

849 Returns 

850 ------- 

851 indices : tuple of arrays. 

852 The `n` arrays of indices corresponding to the locations where 

853 ``mask_func(np.ones((n, n)), k)`` is True. 

854 

855 See Also 

856 -------- 

857 triu, tril, triu_indices, tril_indices 

858 

859 Examples 

860 -------- 

861 >>> import numpy as np 

862 

863 These are the indices that would allow you to access the upper triangular 

864 part of any 3x3 array: 

865 

866 >>> iu = np.mask_indices(3, np.triu) 

867 

868 For example, if `a` is a 3x3 array: 

869 

870 >>> a = np.arange(9).reshape(3, 3) 

871 >>> a 

872 array([[0, 1, 2], 

873 [3, 4, 5], 

874 [6, 7, 8]]) 

875 >>> a[iu] 

876 array([0, 1, 2, 4, 5, 8]) 

877 

878 An offset can be passed also to the masking function. This gets us the 

879 indices starting on the first diagonal right of the main one: 

880 

881 >>> iu1 = np.mask_indices(3, np.triu, 1) 

882 

883 with which we now extract only three elements: 

884 

885 >>> a[iu1] 

886 array([1, 2, 5]) 

887 

888 """ 

889 m = ones((n, n), int) 

890 a = mask_func(m, k) 

891 return nonzero(a != 0) 

892 

893 

894@set_module('numpy') 

895def tril_indices(n, k=0, m=None): 

896 """ 

897 Return the indices for the lower-triangle of an (n, m) array. 

898 

899 Parameters 

900 ---------- 

901 n : int 

902 The row dimension of the arrays for which the returned 

903 indices will be valid. 

904 k : int, optional 

905 Diagonal offset (see `tril` for details). 

906 m : int, optional 

907 The column dimension of the arrays for which the returned 

908 arrays will be valid. 

909 By default `m` is taken equal to `n`. 

910 

911 

912 Returns 

913 ------- 

914 inds : tuple of arrays 

915 The row and column indices, respectively. The row indices are sorted 

916 in non-decreasing order, and the correspdonding column indices are 

917 strictly increasing for each row. 

918 

919 See also 

920 -------- 

921 triu_indices : similar function, for upper-triangular. 

922 mask_indices : generic function accepting an arbitrary mask function. 

923 tril, triu 

924 

925 Examples 

926 -------- 

927 >>> import numpy as np 

928 

929 Compute two different sets of indices to access 4x4 arrays, one for the 

930 lower triangular part starting at the main diagonal, and one starting two 

931 diagonals further right: 

932 

933 >>> il1 = np.tril_indices(4) 

934 >>> il1 

935 (array([0, 1, 1, 2, 2, 2, 3, 3, 3, 3]), array([0, 0, 1, 0, 1, 2, 0, 1, 2, 3])) 

936 

937 Note that row indices (first array) are non-decreasing, and the corresponding 

938 column indices (second array) are strictly increasing for each row. 

939 Here is how they can be used with a sample array: 

940 

941 >>> a = np.arange(16).reshape(4, 4) 

942 >>> a 

943 array([[ 0, 1, 2, 3], 

944 [ 4, 5, 6, 7], 

945 [ 8, 9, 10, 11], 

946 [12, 13, 14, 15]]) 

947 

948 Both for indexing: 

949 

950 >>> a[il1] 

951 array([ 0, 4, 5, ..., 13, 14, 15]) 

952 

953 And for assigning values: 

954 

955 >>> a[il1] = -1 

956 >>> a 

957 array([[-1, 1, 2, 3], 

958 [-1, -1, 6, 7], 

959 [-1, -1, -1, 11], 

960 [-1, -1, -1, -1]]) 

961 

962 These cover almost the whole array (two diagonals right of the main one): 

963 

964 >>> il2 = np.tril_indices(4, 2) 

965 >>> a[il2] = -10 

966 >>> a 

967 array([[-10, -10, -10, 3], 

968 [-10, -10, -10, -10], 

969 [-10, -10, -10, -10], 

970 [-10, -10, -10, -10]]) 

971 

972 """ 

973 tri_ = tri(n, m, k=k, dtype=bool) 

974 

975 return tuple(broadcast_to(inds, tri_.shape)[tri_] 

976 for inds in indices(tri_.shape, sparse=True)) 

977 

978 

979def _trilu_indices_form_dispatcher(arr, k=None): 

980 return (arr,) 

981 

982 

983@array_function_dispatch(_trilu_indices_form_dispatcher) 

984def tril_indices_from(arr, k=0): 

985 """ 

986 Return the indices for the lower-triangle of arr. 

987 

988 See `tril_indices` for full details. 

989 

990 Parameters 

991 ---------- 

992 arr : array_like 

993 The indices will be valid for square arrays whose dimensions are 

994 the same as arr. 

995 k : int, optional 

996 Diagonal offset (see `tril` for details). 

997 

998 Examples 

999 -------- 

1000 >>> import numpy as np 

1001 

1002 Create a 4 by 4 array 

1003 

1004 >>> a = np.arange(16).reshape(4, 4) 

1005 >>> a 

1006 array([[ 0, 1, 2, 3], 

1007 [ 4, 5, 6, 7], 

1008 [ 8, 9, 10, 11], 

1009 [12, 13, 14, 15]]) 

1010 

1011 Pass the array to get the indices of the lower triangular elements. 

1012 

1013 >>> trili = np.tril_indices_from(a) 

1014 >>> trili 

1015 (array([0, 1, 1, 2, 2, 2, 3, 3, 3, 3]), array([0, 0, 1, 0, 1, 2, 0, 1, 2, 3])) 

1016 

1017 >>> a[trili] 

1018 array([ 0, 4, 5, 8, 9, 10, 12, 13, 14, 15]) 

1019 

1020 This is syntactic sugar for tril_indices(). 

1021 

1022 >>> np.tril_indices(a.shape[0]) 

1023 (array([0, 1, 1, 2, 2, 2, 3, 3, 3, 3]), array([0, 0, 1, 0, 1, 2, 0, 1, 2, 3])) 

1024 

1025 Use the `k` parameter to return the indices for the lower triangular array 

1026 up to the k-th diagonal. 

1027 

1028 >>> trili1 = np.tril_indices_from(a, k=1) 

1029 >>> a[trili1] 

1030 array([ 0, 1, 4, 5, 6, 8, 9, 10, 11, 12, 13, 14, 15]) 

1031 

1032 See Also 

1033 -------- 

1034 tril_indices, tril, triu_indices_from 

1035 """ 

1036 if arr.ndim != 2: 

1037 raise ValueError("input array must be 2-d") 

1038 return tril_indices(arr.shape[-2], k=k, m=arr.shape[-1]) 

1039 

1040 

1041@set_module('numpy') 

1042def triu_indices(n, k=0, m=None): 

1043 """ 

1044 Return the indices for the upper-triangle of an (n, m) array. 

1045 

1046 Parameters 

1047 ---------- 

1048 n : int 

1049 The size of the arrays for which the returned indices will 

1050 be valid. 

1051 k : int, optional 

1052 Diagonal offset (see `triu` for details). 

1053 m : int, optional 

1054 The column dimension of the arrays for which the returned 

1055 arrays will be valid. 

1056 By default `m` is taken equal to `n`. 

1057 

1058 

1059 Returns 

1060 ------- 

1061 inds : tuple, shape(2) of ndarrays, shape(`n`) 

1062 The row and column indices, respectively. The row indices are sorted 

1063 in non-decreasing order, and the correspdonding column indices are 

1064 strictly increasing for each row. 

1065 

1066 See also 

1067 -------- 

1068 tril_indices : similar function, for lower-triangular. 

1069 mask_indices : generic function accepting an arbitrary mask function. 

1070 triu, tril 

1071 

1072 Examples 

1073 -------- 

1074 >>> import numpy as np 

1075 

1076 Compute two different sets of indices to access 4x4 arrays, one for the 

1077 upper triangular part starting at the main diagonal, and one starting two 

1078 diagonals further right: 

1079 

1080 >>> iu1 = np.triu_indices(4) 

1081 >>> iu1 

1082 (array([0, 0, 0, 0, 1, 1, 1, 2, 2, 3]), array([0, 1, 2, 3, 1, 2, 3, 2, 3, 3])) 

1083 

1084 Note that row indices (first array) are non-decreasing, and the corresponding 

1085 column indices (second array) are strictly increasing for each row. 

1086 

1087 Here is how they can be used with a sample array: 

1088 

1089 >>> a = np.arange(16).reshape(4, 4) 

1090 >>> a 

1091 array([[ 0, 1, 2, 3], 

1092 [ 4, 5, 6, 7], 

1093 [ 8, 9, 10, 11], 

1094 [12, 13, 14, 15]]) 

1095 

1096 Both for indexing: 

1097 

1098 >>> a[iu1] 

1099 array([ 0, 1, 2, ..., 10, 11, 15]) 

1100 

1101 And for assigning values: 

1102 

1103 >>> a[iu1] = -1 

1104 >>> a 

1105 array([[-1, -1, -1, -1], 

1106 [ 4, -1, -1, -1], 

1107 [ 8, 9, -1, -1], 

1108 [12, 13, 14, -1]]) 

1109 

1110 These cover only a small part of the whole array (two diagonals right 

1111 of the main one): 

1112 

1113 >>> iu2 = np.triu_indices(4, 2) 

1114 >>> a[iu2] = -10 

1115 >>> a 

1116 array([[ -1, -1, -10, -10], 

1117 [ 4, -1, -1, -10], 

1118 [ 8, 9, -1, -1], 

1119 [ 12, 13, 14, -1]]) 

1120 

1121 """ 

1122 tri_ = ~tri(n, m, k=k - 1, dtype=bool) 

1123 

1124 return tuple(broadcast_to(inds, tri_.shape)[tri_] 

1125 for inds in indices(tri_.shape, sparse=True)) 

1126 

1127 

1128@array_function_dispatch(_trilu_indices_form_dispatcher) 

1129def triu_indices_from(arr, k=0): 

1130 """ 

1131 Return the indices for the upper-triangle of arr. 

1132 

1133 See `triu_indices` for full details. 

1134 

1135 Parameters 

1136 ---------- 

1137 arr : ndarray, shape(N, N) 

1138 The indices will be valid for square arrays. 

1139 k : int, optional 

1140 Diagonal offset (see `triu` for details). 

1141 

1142 Returns 

1143 ------- 

1144 triu_indices_from : tuple, shape(2) of ndarray, shape(N) 

1145 Indices for the upper-triangle of `arr`. 

1146 

1147 Examples 

1148 -------- 

1149 >>> import numpy as np 

1150 

1151 Create a 4 by 4 array 

1152 

1153 >>> a = np.arange(16).reshape(4, 4) 

1154 >>> a 

1155 array([[ 0, 1, 2, 3], 

1156 [ 4, 5, 6, 7], 

1157 [ 8, 9, 10, 11], 

1158 [12, 13, 14, 15]]) 

1159 

1160 Pass the array to get the indices of the upper triangular elements. 

1161 

1162 >>> triui = np.triu_indices_from(a) 

1163 >>> triui 

1164 (array([0, 0, 0, 0, 1, 1, 1, 2, 2, 3]), array([0, 1, 2, 3, 1, 2, 3, 2, 3, 3])) 

1165 

1166 >>> a[triui] 

1167 array([ 0, 1, 2, 3, 5, 6, 7, 10, 11, 15]) 

1168 

1169 This is syntactic sugar for triu_indices(). 

1170 

1171 >>> np.triu_indices(a.shape[0]) 

1172 (array([0, 0, 0, 0, 1, 1, 1, 2, 2, 3]), array([0, 1, 2, 3, 1, 2, 3, 2, 3, 3])) 

1173 

1174 Use the `k` parameter to return the indices for the upper triangular array 

1175 from the k-th diagonal. 

1176 

1177 >>> triuim1 = np.triu_indices_from(a, k=1) 

1178 >>> a[triuim1] 

1179 array([ 1, 2, 3, 6, 7, 11]) 

1180 

1181 

1182 See Also 

1183 -------- 

1184 triu_indices, triu, tril_indices_from 

1185 """ 

1186 if arr.ndim != 2: 

1187 raise ValueError("input array must be 2-d") 

1188 return triu_indices(arr.shape[-2], k=k, m=arr.shape[-1])