1""" Basic functions for manipulating 2d arrays
2
3"""
4import functools
5import operator
6
7from numpy.core.numeric import (
8 asanyarray, arange, zeros, greater_equal, multiply, ones,
9 asarray, where, int8, int16, int32, int64, intp, empty, promote_types,
10 diagonal, nonzero, indices
11 )
12from numpy.core.overrides import set_array_function_like_doc, set_module
13from numpy.core import overrides
14from numpy.core import iinfo
15from numpy.lib.stride_tricks import broadcast_to
16
17
18__all__ = [
19 'diag', 'diagflat', 'eye', 'fliplr', 'flipud', 'tri', 'triu',
20 'tril', 'vander', 'histogram2d', 'mask_indices', 'tril_indices',
21 'tril_indices_from', 'triu_indices', 'triu_indices_from', ]
22
23
24array_function_dispatch = functools.partial(
25 overrides.array_function_dispatch, module='numpy')
26
27
28i1 = iinfo(int8)
29i2 = iinfo(int16)
30i4 = iinfo(int32)
31
32
33def _min_int(low, high):
34 """ get small int that fits the range """
35 if high <= i1.max and low >= i1.min:
36 return int8
37 if high <= i2.max and low >= i2.min:
38 return int16
39 if high <= i4.max and low >= i4.min:
40 return int32
41 return int64
42
43
44def _flip_dispatcher(m):
45 return (m,)
46
47
48@array_function_dispatch(_flip_dispatcher)
49def fliplr(m):
50 """
51 Reverse the order of elements along axis 1 (left/right).
52
53 For a 2-D array, this flips the entries in each row in the left/right
54 direction. Columns are preserved, but appear in a different order than
55 before.
56
57 Parameters
58 ----------
59 m : array_like
60 Input array, must be at least 2-D.
61
62 Returns
63 -------
64 f : ndarray
65 A view of `m` with the columns reversed. Since a view
66 is returned, this operation is :math:`\\mathcal O(1)`.
67
68 See Also
69 --------
70 flipud : Flip array in the up/down direction.
71 flip : Flip array in one or more dimensions.
72 rot90 : Rotate array counterclockwise.
73
74 Notes
75 -----
76 Equivalent to ``m[:,::-1]`` or ``np.flip(m, axis=1)``.
77 Requires the array to be at least 2-D.
78
79 Examples
80 --------
81 >>> A = np.diag([1.,2.,3.])
82 >>> A
83 array([[1., 0., 0.],
84 [0., 2., 0.],
85 [0., 0., 3.]])
86 >>> np.fliplr(A)
87 array([[0., 0., 1.],
88 [0., 2., 0.],
89 [3., 0., 0.]])
90
91 >>> A = np.random.randn(2,3,5)
92 >>> np.all(np.fliplr(A) == A[:,::-1,...])
93 True
94
95 """
96 m = asanyarray(m)
97 if m.ndim < 2:
98 raise ValueError("Input must be >= 2-d.")
99 return m[:, ::-1]
100
101
102@array_function_dispatch(_flip_dispatcher)
103def flipud(m):
104 """
105 Reverse the order of elements along axis 0 (up/down).
106
107 For a 2-D array, this flips the entries in each column in the up/down
108 direction. Rows are preserved, but appear in a different order than before.
109
110 Parameters
111 ----------
112 m : array_like
113 Input array.
114
115 Returns
116 -------
117 out : array_like
118 A view of `m` with the rows reversed. Since a view is
119 returned, this operation is :math:`\\mathcal O(1)`.
120
121 See Also
122 --------
123 fliplr : Flip array in the left/right direction.
124 flip : Flip array in one or more dimensions.
125 rot90 : Rotate array counterclockwise.
126
127 Notes
128 -----
129 Equivalent to ``m[::-1, ...]`` or ``np.flip(m, axis=0)``.
130 Requires the array to be at least 1-D.
131
132 Examples
133 --------
134 >>> A = np.diag([1.0, 2, 3])
135 >>> A
136 array([[1., 0., 0.],
137 [0., 2., 0.],
138 [0., 0., 3.]])
139 >>> np.flipud(A)
140 array([[0., 0., 3.],
141 [0., 2., 0.],
142 [1., 0., 0.]])
143
144 >>> A = np.random.randn(2,3,5)
145 >>> np.all(np.flipud(A) == A[::-1,...])
146 True
147
148 >>> np.flipud([1,2])
149 array([2, 1])
150
151 """
152 m = asanyarray(m)
153 if m.ndim < 1:
154 raise ValueError("Input must be >= 1-d.")
155 return m[::-1, ...]
156
157
158@set_array_function_like_doc
159@set_module('numpy')
160def eye(N, M=None, k=0, dtype=float, order='C', *, like=None):
161 """
162 Return a 2-D array with ones on the diagonal and zeros elsewhere.
163
164 Parameters
165 ----------
166 N : int
167 Number of rows in the output.
168 M : int, optional
169 Number of columns in the output. If None, defaults to `N`.
170 k : int, optional
171 Index of the diagonal: 0 (the default) refers to the main diagonal,
172 a positive value refers to an upper diagonal, and a negative value
173 to a lower diagonal.
174 dtype : data-type, optional
175 Data-type of the returned array.
176 order : {'C', 'F'}, optional
177 Whether the output should be stored in row-major (C-style) or
178 column-major (Fortran-style) order in memory.
179
180 .. versionadded:: 1.14.0
181 ${ARRAY_FUNCTION_LIKE}
182
183 .. versionadded:: 1.20.0
184
185 Returns
186 -------
187 I : ndarray of shape (N,M)
188 An array where all elements are equal to zero, except for the `k`-th
189 diagonal, whose values are equal to one.
190
191 See Also
192 --------
193 identity : (almost) equivalent function
194 diag : diagonal 2-D array from a 1-D array specified by the user.
195
196 Examples
197 --------
198 >>> np.eye(2, dtype=int)
199 array([[1, 0],
200 [0, 1]])
201 >>> np.eye(3, k=1)
202 array([[0., 1., 0.],
203 [0., 0., 1.],
204 [0., 0., 0.]])
205
206 """
207 if like is not None:
208 return _eye_with_like(like, N, M=M, k=k, dtype=dtype, order=order)
209 if M is None:
210 M = N
211 m = zeros((N, M), dtype=dtype, order=order)
212 if k >= M:
213 return m
214 # Ensure M and k are integers, so we don't get any surprise casting
215 # results in the expressions `M-k` and `M+1` used below. This avoids
216 # a problem with inputs with type (for example) np.uint64.
217 M = operator.index(M)
218 k = operator.index(k)
219 if k >= 0:
220 i = k
221 else:
222 i = (-k) * M
223 m[:M-k].flat[i::M+1] = 1
224 return m
225
226
227_eye_with_like = array_function_dispatch()(eye)
228
229
230def _diag_dispatcher(v, k=None):
231 return (v,)
232
233
234@array_function_dispatch(_diag_dispatcher)
235def diag(v, k=0):
236 """
237 Extract a diagonal or construct a diagonal array.
238
239 See the more detailed documentation for ``numpy.diagonal`` if you use this
240 function to extract a diagonal and wish to write to the resulting array;
241 whether it returns a copy or a view depends on what version of numpy you
242 are using.
243
244 Parameters
245 ----------
246 v : array_like
247 If `v` is a 2-D array, return a copy of its `k`-th diagonal.
248 If `v` is a 1-D array, return a 2-D array with `v` on the `k`-th
249 diagonal.
250 k : int, optional
251 Diagonal in question. The default is 0. Use `k>0` for diagonals
252 above the main diagonal, and `k<0` for diagonals below the main
253 diagonal.
254
255 Returns
256 -------
257 out : ndarray
258 The extracted diagonal or constructed diagonal array.
259
260 See Also
261 --------
262 diagonal : Return specified diagonals.
263 diagflat : Create a 2-D array with the flattened input as a diagonal.
264 trace : Sum along diagonals.
265 triu : Upper triangle of an array.
266 tril : Lower triangle of an array.
267
268 Examples
269 --------
270 >>> x = np.arange(9).reshape((3,3))
271 >>> x
272 array([[0, 1, 2],
273 [3, 4, 5],
274 [6, 7, 8]])
275
276 >>> np.diag(x)
277 array([0, 4, 8])
278 >>> np.diag(x, k=1)
279 array([1, 5])
280 >>> np.diag(x, k=-1)
281 array([3, 7])
282
283 >>> np.diag(np.diag(x))
284 array([[0, 0, 0],
285 [0, 4, 0],
286 [0, 0, 8]])
287
288 """
289 v = asanyarray(v)
290 s = v.shape
291 if len(s) == 1:
292 n = s[0]+abs(k)
293 res = zeros((n, n), v.dtype)
294 if k >= 0:
295 i = k
296 else:
297 i = (-k) * n
298 res[:n-k].flat[i::n+1] = v
299 return res
300 elif len(s) == 2:
301 return diagonal(v, k)
302 else:
303 raise ValueError("Input must be 1- or 2-d.")
304
305
306@array_function_dispatch(_diag_dispatcher)
307def diagflat(v, k=0):
308 """
309 Create a two-dimensional array with the flattened input as a diagonal.
310
311 Parameters
312 ----------
313 v : array_like
314 Input data, which is flattened and set as the `k`-th
315 diagonal of the output.
316 k : int, optional
317 Diagonal to set; 0, the default, corresponds to the "main" diagonal,
318 a positive (negative) `k` giving the number of the diagonal above
319 (below) the main.
320
321 Returns
322 -------
323 out : ndarray
324 The 2-D output array.
325
326 See Also
327 --------
328 diag : MATLAB work-alike for 1-D and 2-D arrays.
329 diagonal : Return specified diagonals.
330 trace : Sum along diagonals.
331
332 Examples
333 --------
334 >>> np.diagflat([[1,2], [3,4]])
335 array([[1, 0, 0, 0],
336 [0, 2, 0, 0],
337 [0, 0, 3, 0],
338 [0, 0, 0, 4]])
339
340 >>> np.diagflat([1,2], 1)
341 array([[0, 1, 0],
342 [0, 0, 2],
343 [0, 0, 0]])
344
345 """
346 try:
347 wrap = v.__array_wrap__
348 except AttributeError:
349 wrap = None
350 v = asarray(v).ravel()
351 s = len(v)
352 n = s + abs(k)
353 res = zeros((n, n), v.dtype)
354 if (k >= 0):
355 i = arange(0, n-k, dtype=intp)
356 fi = i+k+i*n
357 else:
358 i = arange(0, n+k, dtype=intp)
359 fi = i+(i-k)*n
360 res.flat[fi] = v
361 if not wrap:
362 return res
363 return wrap(res)
364
365
366@set_array_function_like_doc
367@set_module('numpy')
368def tri(N, M=None, k=0, dtype=float, *, like=None):
369 """
370 An array with ones at and below the given diagonal and zeros elsewhere.
371
372 Parameters
373 ----------
374 N : int
375 Number of rows in the array.
376 M : int, optional
377 Number of columns in the array.
378 By default, `M` is taken equal to `N`.
379 k : int, optional
380 The sub-diagonal at and below which the array is filled.
381 `k` = 0 is the main diagonal, while `k` < 0 is below it,
382 and `k` > 0 is above. The default is 0.
383 dtype : dtype, optional
384 Data type of the returned array. The default is float.
385 ${ARRAY_FUNCTION_LIKE}
386
387 .. versionadded:: 1.20.0
388
389 Returns
390 -------
391 tri : ndarray of shape (N, M)
392 Array with its lower triangle filled with ones and zero elsewhere;
393 in other words ``T[i,j] == 1`` for ``j <= i + k``, 0 otherwise.
394
395 Examples
396 --------
397 >>> np.tri(3, 5, 2, dtype=int)
398 array([[1, 1, 1, 0, 0],
399 [1, 1, 1, 1, 0],
400 [1, 1, 1, 1, 1]])
401
402 >>> np.tri(3, 5, -1)
403 array([[0., 0., 0., 0., 0.],
404 [1., 0., 0., 0., 0.],
405 [1., 1., 0., 0., 0.]])
406
407 """
408 if like is not None:
409 return _tri_with_like(like, N, M=M, k=k, dtype=dtype)
410
411 if M is None:
412 M = N
413
414 m = greater_equal.outer(arange(N, dtype=_min_int(0, N)),
415 arange(-k, M-k, dtype=_min_int(-k, M - k)))
416
417 # Avoid making a copy if the requested type is already bool
418 m = m.astype(dtype, copy=False)
419
420 return m
421
422
423_tri_with_like = array_function_dispatch()(tri)
424
425
426def _trilu_dispatcher(m, k=None):
427 return (m,)
428
429
430@array_function_dispatch(_trilu_dispatcher)
431def tril(m, k=0):
432 """
433 Lower triangle of an array.
434
435 Return a copy of an array with elements above the `k`-th diagonal zeroed.
436 For arrays with ``ndim`` exceeding 2, `tril` will apply to the final two
437 axes.
438
439 Parameters
440 ----------
441 m : array_like, shape (..., M, N)
442 Input array.
443 k : int, optional
444 Diagonal above which to zero elements. `k = 0` (the default) is the
445 main diagonal, `k < 0` is below it and `k > 0` is above.
446
447 Returns
448 -------
449 tril : ndarray, shape (..., M, N)
450 Lower triangle of `m`, of same shape and data-type as `m`.
451
452 See Also
453 --------
454 triu : same thing, only for the upper triangle
455
456 Examples
457 --------
458 >>> np.tril([[1,2,3],[4,5,6],[7,8,9],[10,11,12]], -1)
459 array([[ 0, 0, 0],
460 [ 4, 0, 0],
461 [ 7, 8, 0],
462 [10, 11, 12]])
463
464 >>> np.tril(np.arange(3*4*5).reshape(3, 4, 5))
465 array([[[ 0, 0, 0, 0, 0],
466 [ 5, 6, 0, 0, 0],
467 [10, 11, 12, 0, 0],
468 [15, 16, 17, 18, 0]],
469 [[20, 0, 0, 0, 0],
470 [25, 26, 0, 0, 0],
471 [30, 31, 32, 0, 0],
472 [35, 36, 37, 38, 0]],
473 [[40, 0, 0, 0, 0],
474 [45, 46, 0, 0, 0],
475 [50, 51, 52, 0, 0],
476 [55, 56, 57, 58, 0]]])
477
478 """
479 m = asanyarray(m)
480 mask = tri(*m.shape[-2:], k=k, dtype=bool)
481
482 return where(mask, m, zeros(1, m.dtype))
483
484
485@array_function_dispatch(_trilu_dispatcher)
486def triu(m, k=0):
487 """
488 Upper triangle of an array.
489
490 Return a copy of an array with the elements below the `k`-th diagonal
491 zeroed. For arrays with ``ndim`` exceeding 2, `triu` will apply to the
492 final two axes.
493
494 Please refer to the documentation for `tril` for further details.
495
496 See Also
497 --------
498 tril : lower triangle of an array
499
500 Examples
501 --------
502 >>> np.triu([[1,2,3],[4,5,6],[7,8,9],[10,11,12]], -1)
503 array([[ 1, 2, 3],
504 [ 4, 5, 6],
505 [ 0, 8, 9],
506 [ 0, 0, 12]])
507
508 >>> np.triu(np.arange(3*4*5).reshape(3, 4, 5))
509 array([[[ 0, 1, 2, 3, 4],
510 [ 0, 6, 7, 8, 9],
511 [ 0, 0, 12, 13, 14],
512 [ 0, 0, 0, 18, 19]],
513 [[20, 21, 22, 23, 24],
514 [ 0, 26, 27, 28, 29],
515 [ 0, 0, 32, 33, 34],
516 [ 0, 0, 0, 38, 39]],
517 [[40, 41, 42, 43, 44],
518 [ 0, 46, 47, 48, 49],
519 [ 0, 0, 52, 53, 54],
520 [ 0, 0, 0, 58, 59]]])
521
522 """
523 m = asanyarray(m)
524 mask = tri(*m.shape[-2:], k=k-1, dtype=bool)
525
526 return where(mask, zeros(1, m.dtype), m)
527
528
529def _vander_dispatcher(x, N=None, increasing=None):
530 return (x,)
531
532
533# Originally borrowed from John Hunter and matplotlib
534@array_function_dispatch(_vander_dispatcher)
535def vander(x, N=None, increasing=False):
536 """
537 Generate a Vandermonde matrix.
538
539 The columns of the output matrix are powers of the input vector. The
540 order of the powers is determined by the `increasing` boolean argument.
541 Specifically, when `increasing` is False, the `i`-th output column is
542 the input vector raised element-wise to the power of ``N - i - 1``. Such
543 a matrix with a geometric progression in each row is named for Alexandre-
544 Theophile Vandermonde.
545
546 Parameters
547 ----------
548 x : array_like
549 1-D input array.
550 N : int, optional
551 Number of columns in the output. If `N` is not specified, a square
552 array is returned (``N = len(x)``).
553 increasing : bool, optional
554 Order of the powers of the columns. If True, the powers increase
555 from left to right, if False (the default) they are reversed.
556
557 .. versionadded:: 1.9.0
558
559 Returns
560 -------
561 out : ndarray
562 Vandermonde matrix. If `increasing` is False, the first column is
563 ``x^(N-1)``, the second ``x^(N-2)`` and so forth. If `increasing` is
564 True, the columns are ``x^0, x^1, ..., x^(N-1)``.
565
566 See Also
567 --------
568 polynomial.polynomial.polyvander
569
570 Examples
571 --------
572 >>> x = np.array([1, 2, 3, 5])
573 >>> N = 3
574 >>> np.vander(x, N)
575 array([[ 1, 1, 1],
576 [ 4, 2, 1],
577 [ 9, 3, 1],
578 [25, 5, 1]])
579
580 >>> np.column_stack([x**(N-1-i) for i in range(N)])
581 array([[ 1, 1, 1],
582 [ 4, 2, 1],
583 [ 9, 3, 1],
584 [25, 5, 1]])
585
586 >>> x = np.array([1, 2, 3, 5])
587 >>> np.vander(x)
588 array([[ 1, 1, 1, 1],
589 [ 8, 4, 2, 1],
590 [ 27, 9, 3, 1],
591 [125, 25, 5, 1]])
592 >>> np.vander(x, increasing=True)
593 array([[ 1, 1, 1, 1],
594 [ 1, 2, 4, 8],
595 [ 1, 3, 9, 27],
596 [ 1, 5, 25, 125]])
597
598 The determinant of a square Vandermonde matrix is the product
599 of the differences between the values of the input vector:
600
601 >>> np.linalg.det(np.vander(x))
602 48.000000000000043 # may vary
603 >>> (5-3)*(5-2)*(5-1)*(3-2)*(3-1)*(2-1)
604 48
605
606 """
607 x = asarray(x)
608 if x.ndim != 1:
609 raise ValueError("x must be a one-dimensional array or sequence.")
610 if N is None:
611 N = len(x)
612
613 v = empty((len(x), N), dtype=promote_types(x.dtype, int))
614 tmp = v[:, ::-1] if not increasing else v
615
616 if N > 0:
617 tmp[:, 0] = 1
618 if N > 1:
619 tmp[:, 1:] = x[:, None]
620 multiply.accumulate(tmp[:, 1:], out=tmp[:, 1:], axis=1)
621
622 return v
623
624
625def _histogram2d_dispatcher(x, y, bins=None, range=None, density=None,
626 weights=None):
627 yield x
628 yield y
629
630 # This terrible logic is adapted from the checks in histogram2d
631 try:
632 N = len(bins)
633 except TypeError:
634 N = 1
635 if N == 2:
636 yield from bins # bins=[x, y]
637 else:
638 yield bins
639
640 yield weights
641
642
643@array_function_dispatch(_histogram2d_dispatcher)
644def histogram2d(x, y, bins=10, range=None, density=None, weights=None):
645 """
646 Compute the bi-dimensional histogram of two data samples.
647
648 Parameters
649 ----------
650 x : array_like, shape (N,)
651 An array containing the x coordinates of the points to be
652 histogrammed.
653 y : array_like, shape (N,)
654 An array containing the y coordinates of the points to be
655 histogrammed.
656 bins : int or array_like or [int, int] or [array, array], optional
657 The bin specification:
658
659 * If int, the number of bins for the two dimensions (nx=ny=bins).
660 * If array_like, the bin edges for the two dimensions
661 (x_edges=y_edges=bins).
662 * If [int, int], the number of bins in each dimension
663 (nx, ny = bins).
664 * If [array, array], the bin edges in each dimension
665 (x_edges, y_edges = bins).
666 * A combination [int, array] or [array, int], where int
667 is the number of bins and array is the bin edges.
668
669 range : array_like, shape(2,2), optional
670 The leftmost and rightmost edges of the bins along each dimension
671 (if not specified explicitly in the `bins` parameters):
672 ``[[xmin, xmax], [ymin, ymax]]``. All values outside of this range
673 will be considered outliers and not tallied in the histogram.
674 density : bool, optional
675 If False, the default, returns the number of samples in each bin.
676 If True, returns the probability *density* function at the bin,
677 ``bin_count / sample_count / bin_area``.
678 weights : array_like, shape(N,), optional
679 An array of values ``w_i`` weighing each sample ``(x_i, y_i)``.
680 Weights are normalized to 1 if `density` is True. If `density` is
681 False, the values of the returned histogram are equal to the sum of
682 the weights belonging to the samples falling into each bin.
683
684 Returns
685 -------
686 H : ndarray, shape(nx, ny)
687 The bi-dimensional histogram of samples `x` and `y`. Values in `x`
688 are histogrammed along the first dimension and values in `y` are
689 histogrammed along the second dimension.
690 xedges : ndarray, shape(nx+1,)
691 The bin edges along the first dimension.
692 yedges : ndarray, shape(ny+1,)
693 The bin edges along the second dimension.
694
695 See Also
696 --------
697 histogram : 1D histogram
698 histogramdd : Multidimensional histogram
699
700 Notes
701 -----
702 When `density` is True, then the returned histogram is the sample
703 density, defined such that the sum over bins of the product
704 ``bin_value * bin_area`` is 1.
705
706 Please note that the histogram does not follow the Cartesian convention
707 where `x` values are on the abscissa and `y` values on the ordinate
708 axis. Rather, `x` is histogrammed along the first dimension of the
709 array (vertical), and `y` along the second dimension of the array
710 (horizontal). This ensures compatibility with `histogramdd`.
711
712 Examples
713 --------
714 >>> from matplotlib.image import NonUniformImage
715 >>> import matplotlib.pyplot as plt
716
717 Construct a 2-D histogram with variable bin width. First define the bin
718 edges:
719
720 >>> xedges = [0, 1, 3, 5]
721 >>> yedges = [0, 2, 3, 4, 6]
722
723 Next we create a histogram H with random bin content:
724
725 >>> x = np.random.normal(2, 1, 100)
726 >>> y = np.random.normal(1, 1, 100)
727 >>> H, xedges, yedges = np.histogram2d(x, y, bins=(xedges, yedges))
728 >>> # Histogram does not follow Cartesian convention (see Notes),
729 >>> # therefore transpose H for visualization purposes.
730 >>> H = H.T
731
732 :func:`imshow <matplotlib.pyplot.imshow>` can only display square bins:
733
734 >>> fig = plt.figure(figsize=(7, 3))
735 >>> ax = fig.add_subplot(131, title='imshow: square bins')
736 >>> plt.imshow(H, interpolation='nearest', origin='lower',
737 ... extent=[xedges[0], xedges[-1], yedges[0], yedges[-1]])
738 <matplotlib.image.AxesImage object at 0x...>
739
740 :func:`pcolormesh <matplotlib.pyplot.pcolormesh>` can display actual edges:
741
742 >>> ax = fig.add_subplot(132, title='pcolormesh: actual edges',
743 ... aspect='equal')
744 >>> X, Y = np.meshgrid(xedges, yedges)
745 >>> ax.pcolormesh(X, Y, H)
746 <matplotlib.collections.QuadMesh object at 0x...>
747
748 :class:`NonUniformImage <matplotlib.image.NonUniformImage>` can be used to
749 display actual bin edges with interpolation:
750
751 >>> ax = fig.add_subplot(133, title='NonUniformImage: interpolated',
752 ... aspect='equal', xlim=xedges[[0, -1]], ylim=yedges[[0, -1]])
753 >>> im = NonUniformImage(ax, interpolation='bilinear')
754 >>> xcenters = (xedges[:-1] + xedges[1:]) / 2
755 >>> ycenters = (yedges[:-1] + yedges[1:]) / 2
756 >>> im.set_data(xcenters, ycenters, H)
757 >>> ax.add_image(im)
758 >>> plt.show()
759
760 It is also possible to construct a 2-D histogram without specifying bin
761 edges:
762
763 >>> # Generate non-symmetric test data
764 >>> n = 10000
765 >>> x = np.linspace(1, 100, n)
766 >>> y = 2*np.log(x) + np.random.rand(n) - 0.5
767 >>> # Compute 2d histogram. Note the order of x/y and xedges/yedges
768 >>> H, yedges, xedges = np.histogram2d(y, x, bins=20)
769
770 Now we can plot the histogram using
771 :func:`pcolormesh <matplotlib.pyplot.pcolormesh>`, and a
772 :func:`hexbin <matplotlib.pyplot.hexbin>` for comparison.
773
774 >>> # Plot histogram using pcolormesh
775 >>> fig, (ax1, ax2) = plt.subplots(ncols=2, sharey=True)
776 >>> ax1.pcolormesh(xedges, yedges, H, cmap='rainbow')
777 >>> ax1.plot(x, 2*np.log(x), 'k-')
778 >>> ax1.set_xlim(x.min(), x.max())
779 >>> ax1.set_ylim(y.min(), y.max())
780 >>> ax1.set_xlabel('x')
781 >>> ax1.set_ylabel('y')
782 >>> ax1.set_title('histogram2d')
783 >>> ax1.grid()
784
785 >>> # Create hexbin plot for comparison
786 >>> ax2.hexbin(x, y, gridsize=20, cmap='rainbow')
787 >>> ax2.plot(x, 2*np.log(x), 'k-')
788 >>> ax2.set_title('hexbin')
789 >>> ax2.set_xlim(x.min(), x.max())
790 >>> ax2.set_xlabel('x')
791 >>> ax2.grid()
792
793 >>> plt.show()
794 """
795 from numpy import histogramdd
796
797 if len(x) != len(y):
798 raise ValueError('x and y must have the same length.')
799
800 try:
801 N = len(bins)
802 except TypeError:
803 N = 1
804
805 if N != 1 and N != 2:
806 xedges = yedges = asarray(bins)
807 bins = [xedges, yedges]
808 hist, edges = histogramdd([x, y], bins, range, density, weights)
809 return hist, edges[0], edges[1]
810
811
812@set_module('numpy')
813def mask_indices(n, mask_func, k=0):
814 """
815 Return the indices to access (n, n) arrays, given a masking function.
816
817 Assume `mask_func` is a function that, for a square array a of size
818 ``(n, n)`` with a possible offset argument `k`, when called as
819 ``mask_func(a, k)`` returns a new array with zeros in certain locations
820 (functions like `triu` or `tril` do precisely this). Then this function
821 returns the indices where the non-zero values would be located.
822
823 Parameters
824 ----------
825 n : int
826 The returned indices will be valid to access arrays of shape (n, n).
827 mask_func : callable
828 A function whose call signature is similar to that of `triu`, `tril`.
829 That is, ``mask_func(x, k)`` returns a boolean array, shaped like `x`.
830 `k` is an optional argument to the function.
831 k : scalar
832 An optional argument which is passed through to `mask_func`. Functions
833 like `triu`, `tril` take a second argument that is interpreted as an
834 offset.
835
836 Returns
837 -------
838 indices : tuple of arrays.
839 The `n` arrays of indices corresponding to the locations where
840 ``mask_func(np.ones((n, n)), k)`` is True.
841
842 See Also
843 --------
844 triu, tril, triu_indices, tril_indices
845
846 Notes
847 -----
848 .. versionadded:: 1.4.0
849
850 Examples
851 --------
852 These are the indices that would allow you to access the upper triangular
853 part of any 3x3 array:
854
855 >>> iu = np.mask_indices(3, np.triu)
856
857 For example, if `a` is a 3x3 array:
858
859 >>> a = np.arange(9).reshape(3, 3)
860 >>> a
861 array([[0, 1, 2],
862 [3, 4, 5],
863 [6, 7, 8]])
864 >>> a[iu]
865 array([0, 1, 2, 4, 5, 8])
866
867 An offset can be passed also to the masking function. This gets us the
868 indices starting on the first diagonal right of the main one:
869
870 >>> iu1 = np.mask_indices(3, np.triu, 1)
871
872 with which we now extract only three elements:
873
874 >>> a[iu1]
875 array([1, 2, 5])
876
877 """
878 m = ones((n, n), int)
879 a = mask_func(m, k)
880 return nonzero(a != 0)
881
882
883@set_module('numpy')
884def tril_indices(n, k=0, m=None):
885 """
886 Return the indices for the lower-triangle of an (n, m) array.
887
888 Parameters
889 ----------
890 n : int
891 The row dimension of the arrays for which the returned
892 indices will be valid.
893 k : int, optional
894 Diagonal offset (see `tril` for details).
895 m : int, optional
896 .. versionadded:: 1.9.0
897
898 The column dimension of the arrays for which the returned
899 arrays will be valid.
900 By default `m` is taken equal to `n`.
901
902
903 Returns
904 -------
905 inds : tuple of arrays
906 The indices for the triangle. The returned tuple contains two arrays,
907 each with the indices along one dimension of the array.
908
909 See also
910 --------
911 triu_indices : similar function, for upper-triangular.
912 mask_indices : generic function accepting an arbitrary mask function.
913 tril, triu
914
915 Notes
916 -----
917 .. versionadded:: 1.4.0
918
919 Examples
920 --------
921 Compute two different sets of indices to access 4x4 arrays, one for the
922 lower triangular part starting at the main diagonal, and one starting two
923 diagonals further right:
924
925 >>> il1 = np.tril_indices(4)
926 >>> il2 = np.tril_indices(4, 2)
927
928 Here is how they can be used with a sample array:
929
930 >>> a = np.arange(16).reshape(4, 4)
931 >>> a
932 array([[ 0, 1, 2, 3],
933 [ 4, 5, 6, 7],
934 [ 8, 9, 10, 11],
935 [12, 13, 14, 15]])
936
937 Both for indexing:
938
939 >>> a[il1]
940 array([ 0, 4, 5, ..., 13, 14, 15])
941
942 And for assigning values:
943
944 >>> a[il1] = -1
945 >>> a
946 array([[-1, 1, 2, 3],
947 [-1, -1, 6, 7],
948 [-1, -1, -1, 11],
949 [-1, -1, -1, -1]])
950
951 These cover almost the whole array (two diagonals right of the main one):
952
953 >>> a[il2] = -10
954 >>> a
955 array([[-10, -10, -10, 3],
956 [-10, -10, -10, -10],
957 [-10, -10, -10, -10],
958 [-10, -10, -10, -10]])
959
960 """
961 tri_ = tri(n, m, k=k, dtype=bool)
962
963 return tuple(broadcast_to(inds, tri_.shape)[tri_]
964 for inds in indices(tri_.shape, sparse=True))
965
966
967def _trilu_indices_form_dispatcher(arr, k=None):
968 return (arr,)
969
970
971@array_function_dispatch(_trilu_indices_form_dispatcher)
972def tril_indices_from(arr, k=0):
973 """
974 Return the indices for the lower-triangle of arr.
975
976 See `tril_indices` for full details.
977
978 Parameters
979 ----------
980 arr : array_like
981 The indices will be valid for square arrays whose dimensions are
982 the same as arr.
983 k : int, optional
984 Diagonal offset (see `tril` for details).
985
986 Examples
987 --------
988
989 Create a 4 by 4 array.
990
991 >>> a = np.arange(16).reshape(4, 4)
992 >>> a
993 array([[ 0, 1, 2, 3],
994 [ 4, 5, 6, 7],
995 [ 8, 9, 10, 11],
996 [12, 13, 14, 15]])
997
998 Pass the array to get the indices of the lower triangular elements.
999
1000 >>> trili = np.tril_indices_from(a)
1001 >>> trili
1002 (array([0, 1, 1, 2, 2, 2, 3, 3, 3, 3]), array([0, 0, 1, 0, 1, 2, 0, 1, 2, 3]))
1003
1004 >>> a[trili]
1005 array([ 0, 4, 5, 8, 9, 10, 12, 13, 14, 15])
1006
1007 This is syntactic sugar for tril_indices().
1008
1009 >>> np.tril_indices(a.shape[0])
1010 (array([0, 1, 1, 2, 2, 2, 3, 3, 3, 3]), array([0, 0, 1, 0, 1, 2, 0, 1, 2, 3]))
1011
1012 Use the `k` parameter to return the indices for the lower triangular array
1013 up to the k-th diagonal.
1014
1015 >>> trili1 = np.tril_indices_from(a, k=1)
1016 >>> a[trili1]
1017 array([ 0, 1, 4, 5, 6, 8, 9, 10, 11, 12, 13, 14, 15])
1018
1019 See Also
1020 --------
1021 tril_indices, tril, triu_indices_from
1022
1023 Notes
1024 -----
1025 .. versionadded:: 1.4.0
1026
1027 """
1028 if arr.ndim != 2:
1029 raise ValueError("input array must be 2-d")
1030 return tril_indices(arr.shape[-2], k=k, m=arr.shape[-1])
1031
1032
1033@set_module('numpy')
1034def triu_indices(n, k=0, m=None):
1035 """
1036 Return the indices for the upper-triangle of an (n, m) array.
1037
1038 Parameters
1039 ----------
1040 n : int
1041 The size of the arrays for which the returned indices will
1042 be valid.
1043 k : int, optional
1044 Diagonal offset (see `triu` for details).
1045 m : int, optional
1046 .. versionadded:: 1.9.0
1047
1048 The column dimension of the arrays for which the returned
1049 arrays will be valid.
1050 By default `m` is taken equal to `n`.
1051
1052
1053 Returns
1054 -------
1055 inds : tuple, shape(2) of ndarrays, shape(`n`)
1056 The indices for the triangle. The returned tuple contains two arrays,
1057 each with the indices along one dimension of the array. Can be used
1058 to slice a ndarray of shape(`n`, `n`).
1059
1060 See also
1061 --------
1062 tril_indices : similar function, for lower-triangular.
1063 mask_indices : generic function accepting an arbitrary mask function.
1064 triu, tril
1065
1066 Notes
1067 -----
1068 .. versionadded:: 1.4.0
1069
1070 Examples
1071 --------
1072 Compute two different sets of indices to access 4x4 arrays, one for the
1073 upper triangular part starting at the main diagonal, and one starting two
1074 diagonals further right:
1075
1076 >>> iu1 = np.triu_indices(4)
1077 >>> iu2 = np.triu_indices(4, 2)
1078
1079 Here is how they can be used with a sample array:
1080
1081 >>> a = np.arange(16).reshape(4, 4)
1082 >>> a
1083 array([[ 0, 1, 2, 3],
1084 [ 4, 5, 6, 7],
1085 [ 8, 9, 10, 11],
1086 [12, 13, 14, 15]])
1087
1088 Both for indexing:
1089
1090 >>> a[iu1]
1091 array([ 0, 1, 2, ..., 10, 11, 15])
1092
1093 And for assigning values:
1094
1095 >>> a[iu1] = -1
1096 >>> a
1097 array([[-1, -1, -1, -1],
1098 [ 4, -1, -1, -1],
1099 [ 8, 9, -1, -1],
1100 [12, 13, 14, -1]])
1101
1102 These cover only a small part of the whole array (two diagonals right
1103 of the main one):
1104
1105 >>> a[iu2] = -10
1106 >>> a
1107 array([[ -1, -1, -10, -10],
1108 [ 4, -1, -1, -10],
1109 [ 8, 9, -1, -1],
1110 [ 12, 13, 14, -1]])
1111
1112 """
1113 tri_ = ~tri(n, m, k=k - 1, dtype=bool)
1114
1115 return tuple(broadcast_to(inds, tri_.shape)[tri_]
1116 for inds in indices(tri_.shape, sparse=True))
1117
1118
1119@array_function_dispatch(_trilu_indices_form_dispatcher)
1120def triu_indices_from(arr, k=0):
1121 """
1122 Return the indices for the upper-triangle of arr.
1123
1124 See `triu_indices` for full details.
1125
1126 Parameters
1127 ----------
1128 arr : ndarray, shape(N, N)
1129 The indices will be valid for square arrays.
1130 k : int, optional
1131 Diagonal offset (see `triu` for details).
1132
1133 Returns
1134 -------
1135 triu_indices_from : tuple, shape(2) of ndarray, shape(N)
1136 Indices for the upper-triangle of `arr`.
1137
1138 Examples
1139 --------
1140
1141 Create a 4 by 4 array.
1142
1143 >>> a = np.arange(16).reshape(4, 4)
1144 >>> a
1145 array([[ 0, 1, 2, 3],
1146 [ 4, 5, 6, 7],
1147 [ 8, 9, 10, 11],
1148 [12, 13, 14, 15]])
1149
1150 Pass the array to get the indices of the upper triangular elements.
1151
1152 >>> triui = np.triu_indices_from(a)
1153 >>> triui
1154 (array([0, 0, 0, 0, 1, 1, 1, 2, 2, 3]), array([0, 1, 2, 3, 1, 2, 3, 2, 3, 3]))
1155
1156 >>> a[triui]
1157 array([ 0, 1, 2, 3, 5, 6, 7, 10, 11, 15])
1158
1159 This is syntactic sugar for triu_indices().
1160
1161 >>> np.triu_indices(a.shape[0])
1162 (array([0, 0, 0, 0, 1, 1, 1, 2, 2, 3]), array([0, 1, 2, 3, 1, 2, 3, 2, 3, 3]))
1163
1164 Use the `k` parameter to return the indices for the upper triangular array
1165 from the k-th diagonal.
1166
1167 >>> triuim1 = np.triu_indices_from(a, k=1)
1168 >>> a[triuim1]
1169 array([ 1, 2, 3, 6, 7, 11])
1170
1171
1172 See Also
1173 --------
1174 triu_indices, triu, tril_indices_from
1175
1176 Notes
1177 -----
1178 .. versionadded:: 1.4.0
1179
1180 """
1181 if arr.ndim != 2:
1182 raise ValueError("input array must be 2-d")
1183 return triu_indices(arr.shape[-2], k=k, m=arr.shape[-1])