koichi12 commited on
Commit
d78dfe4
·
verified ·
1 Parent(s): 70a8abe

Add files using upload-large-folder tool

Browse files
This view is limited to 50 files because it contains too many changes.   See raw diff
Files changed (50) hide show
  1. .gitattributes +3 -0
  2. .venv/lib/python3.11/site-packages/numpy/__pycache__/__config__.cpython-311.pyc +0 -0
  3. .venv/lib/python3.11/site-packages/numpy/__pycache__/__init__.cpython-311.pyc +0 -0
  4. .venv/lib/python3.11/site-packages/numpy/__pycache__/_distributor_init.cpython-311.pyc +0 -0
  5. .venv/lib/python3.11/site-packages/numpy/__pycache__/_globals.cpython-311.pyc +0 -0
  6. .venv/lib/python3.11/site-packages/numpy/__pycache__/_pytesttester.cpython-311.pyc +0 -0
  7. .venv/lib/python3.11/site-packages/numpy/__pycache__/conftest.cpython-311.pyc +0 -0
  8. .venv/lib/python3.11/site-packages/numpy/__pycache__/ctypeslib.cpython-311.pyc +0 -0
  9. .venv/lib/python3.11/site-packages/numpy/__pycache__/dtypes.cpython-311.pyc +0 -0
  10. .venv/lib/python3.11/site-packages/numpy/__pycache__/exceptions.cpython-311.pyc +0 -0
  11. .venv/lib/python3.11/site-packages/numpy/__pycache__/matlib.cpython-311.pyc +0 -0
  12. .venv/lib/python3.11/site-packages/numpy/__pycache__/version.cpython-311.pyc +0 -0
  13. .venv/lib/python3.11/site-packages/numpy/_core/__init__.py +4 -0
  14. .venv/lib/python3.11/site-packages/numpy/_core/__init__.pyi +0 -0
  15. .venv/lib/python3.11/site-packages/numpy/_core/__pycache__/__init__.cpython-311.pyc +0 -0
  16. .venv/lib/python3.11/site-packages/numpy/_core/__pycache__/_dtype.cpython-311.pyc +0 -0
  17. .venv/lib/python3.11/site-packages/numpy/_core/__pycache__/_dtype_ctypes.cpython-311.pyc +0 -0
  18. .venv/lib/python3.11/site-packages/numpy/_core/__pycache__/_internal.cpython-311.pyc +0 -0
  19. .venv/lib/python3.11/site-packages/numpy/_core/__pycache__/_multiarray_umath.cpython-311.pyc +0 -0
  20. .venv/lib/python3.11/site-packages/numpy/_core/__pycache__/multiarray.cpython-311.pyc +0 -0
  21. .venv/lib/python3.11/site-packages/numpy/_core/__pycache__/umath.cpython-311.pyc +0 -0
  22. .venv/lib/python3.11/site-packages/numpy/_core/_dtype.py +6 -0
  23. .venv/lib/python3.11/site-packages/numpy/_core/_dtype_ctypes.py +6 -0
  24. .venv/lib/python3.11/site-packages/numpy/_core/_internal.py +6 -0
  25. .venv/lib/python3.11/site-packages/numpy/_core/_multiarray_umath.py +6 -0
  26. .venv/lib/python3.11/site-packages/numpy/_core/multiarray.py +6 -0
  27. .venv/lib/python3.11/site-packages/numpy/_core/umath.py +6 -0
  28. .venv/lib/python3.11/site-packages/numpy/distutils/__pycache__/ccompiler_opt.cpython-311.pyc +3 -0
  29. .venv/lib/python3.11/site-packages/numpy/distutils/__pycache__/misc_util.cpython-311.pyc +3 -0
  30. .venv/lib/python3.11/site-packages/numpy/distutils/__pycache__/system_info.cpython-311.pyc +3 -0
  31. .venv/lib/python3.11/site-packages/numpy/distutils/fcompiler/__pycache__/__init__.cpython-311.pyc +0 -0
  32. .venv/lib/python3.11/site-packages/numpy/distutils/fcompiler/__pycache__/intel.cpython-311.pyc +0 -0
  33. .venv/lib/python3.11/site-packages/numpy/distutils/fcompiler/__pycache__/mips.cpython-311.pyc +0 -0
  34. .venv/lib/python3.11/site-packages/numpy/distutils/fcompiler/__pycache__/none.cpython-311.pyc +0 -0
  35. .venv/lib/python3.11/site-packages/numpy/distutils/fcompiler/__pycache__/pathf95.cpython-311.pyc +0 -0
  36. .venv/lib/python3.11/site-packages/numpy/distutils/fcompiler/__pycache__/sun.cpython-311.pyc +0 -0
  37. .venv/lib/python3.11/site-packages/numpy/ma/API_CHANGES.txt +135 -0
  38. .venv/lib/python3.11/site-packages/numpy/ma/LICENSE +24 -0
  39. .venv/lib/python3.11/site-packages/numpy/ma/README.rst +236 -0
  40. .venv/lib/python3.11/site-packages/numpy/ma/__init__.py +54 -0
  41. .venv/lib/python3.11/site-packages/numpy/ma/__init__.pyi +234 -0
  42. .venv/lib/python3.11/site-packages/numpy/ma/__pycache__/__init__.cpython-311.pyc +0 -0
  43. .venv/lib/python3.11/site-packages/numpy/ma/__pycache__/extras.cpython-311.pyc +0 -0
  44. .venv/lib/python3.11/site-packages/numpy/ma/__pycache__/mrecords.cpython-311.pyc +0 -0
  45. .venv/lib/python3.11/site-packages/numpy/ma/__pycache__/setup.cpython-311.pyc +0 -0
  46. .venv/lib/python3.11/site-packages/numpy/ma/__pycache__/testutils.cpython-311.pyc +0 -0
  47. .venv/lib/python3.11/site-packages/numpy/ma/__pycache__/timer_comparison.cpython-311.pyc +0 -0
  48. .venv/lib/python3.11/site-packages/numpy/ma/core.py +0 -0
  49. .venv/lib/python3.11/site-packages/numpy/ma/core.pyi +471 -0
  50. .venv/lib/python3.11/site-packages/numpy/ma/extras.py +2133 -0
.gitattributes CHANGED
@@ -382,3 +382,6 @@ tuning-competition-baseline/.venv/lib/python3.11/site-packages/nvidia/cudnn/lib/
382
  .venv/lib/python3.11/site-packages/numpy/core/tests/__pycache__/test_ufunc.cpython-311.pyc filter=lfs diff=lfs merge=lfs -text
383
  .venv/lib/python3.11/site-packages/numpy/core/tests/__pycache__/test_nditer.cpython-311.pyc filter=lfs diff=lfs merge=lfs -text
384
  .venv/lib/python3.11/site-packages/numpy/core/tests/__pycache__/test_numeric.cpython-311.pyc filter=lfs diff=lfs merge=lfs -text
 
 
 
 
382
  .venv/lib/python3.11/site-packages/numpy/core/tests/__pycache__/test_ufunc.cpython-311.pyc filter=lfs diff=lfs merge=lfs -text
383
  .venv/lib/python3.11/site-packages/numpy/core/tests/__pycache__/test_nditer.cpython-311.pyc filter=lfs diff=lfs merge=lfs -text
384
  .venv/lib/python3.11/site-packages/numpy/core/tests/__pycache__/test_numeric.cpython-311.pyc filter=lfs diff=lfs merge=lfs -text
385
+ .venv/lib/python3.11/site-packages/numpy/distutils/__pycache__/misc_util.cpython-311.pyc filter=lfs diff=lfs merge=lfs -text
386
+ .venv/lib/python3.11/site-packages/numpy/distutils/__pycache__/ccompiler_opt.cpython-311.pyc filter=lfs diff=lfs merge=lfs -text
387
+ .venv/lib/python3.11/site-packages/numpy/distutils/__pycache__/system_info.cpython-311.pyc filter=lfs diff=lfs merge=lfs -text
.venv/lib/python3.11/site-packages/numpy/__pycache__/__config__.cpython-311.pyc ADDED
Binary file (5.79 kB). View file
 
.venv/lib/python3.11/site-packages/numpy/__pycache__/__init__.cpython-311.pyc ADDED
Binary file (16.9 kB). View file
 
.venv/lib/python3.11/site-packages/numpy/__pycache__/_distributor_init.cpython-311.pyc ADDED
Binary file (690 Bytes). View file
 
.venv/lib/python3.11/site-packages/numpy/__pycache__/_globals.cpython-311.pyc ADDED
Binary file (4.16 kB). View file
 
.venv/lib/python3.11/site-packages/numpy/__pycache__/_pytesttester.cpython-311.pyc ADDED
Binary file (7.55 kB). View file
 
.venv/lib/python3.11/site-packages/numpy/__pycache__/conftest.cpython-311.pyc ADDED
Binary file (6.19 kB). View file
 
.venv/lib/python3.11/site-packages/numpy/__pycache__/ctypeslib.cpython-311.pyc ADDED
Binary file (21.5 kB). View file
 
.venv/lib/python3.11/site-packages/numpy/__pycache__/dtypes.cpython-311.pyc ADDED
Binary file (2.62 kB). View file
 
.venv/lib/python3.11/site-packages/numpy/__pycache__/exceptions.cpython-311.pyc ADDED
Binary file (8.61 kB). View file
 
.venv/lib/python3.11/site-packages/numpy/__pycache__/matlib.cpython-311.pyc ADDED
Binary file (12.1 kB). View file
 
.venv/lib/python3.11/site-packages/numpy/__pycache__/version.cpython-311.pyc ADDED
Binary file (460 Bytes). View file
 
.venv/lib/python3.11/site-packages/numpy/_core/__init__.py ADDED
@@ -0,0 +1,4 @@
 
 
 
 
 
1
+ """
2
+ This private module only contains stubs for interoperability with
3
+ NumPy 2.0 pickled arrays. It may not be used by the end user.
4
+ """
.venv/lib/python3.11/site-packages/numpy/_core/__init__.pyi ADDED
File without changes
.venv/lib/python3.11/site-packages/numpy/_core/__pycache__/__init__.cpython-311.pyc ADDED
Binary file (335 Bytes). View file
 
.venv/lib/python3.11/site-packages/numpy/_core/__pycache__/_dtype.cpython-311.pyc ADDED
Binary file (429 Bytes). View file
 
.venv/lib/python3.11/site-packages/numpy/_core/__pycache__/_dtype_ctypes.cpython-311.pyc ADDED
Binary file (444 Bytes). View file
 
.venv/lib/python3.11/site-packages/numpy/_core/__pycache__/_internal.cpython-311.pyc ADDED
Binary file (436 Bytes). View file
 
.venv/lib/python3.11/site-packages/numpy/_core/__pycache__/_multiarray_umath.cpython-311.pyc ADDED
Binary file (454 Bytes). View file
 
.venv/lib/python3.11/site-packages/numpy/_core/__pycache__/multiarray.cpython-311.pyc ADDED
Binary file (438 Bytes). View file
 
.venv/lib/python3.11/site-packages/numpy/_core/__pycache__/umath.cpython-311.pyc ADDED
Binary file (425 Bytes). View file
 
.venv/lib/python3.11/site-packages/numpy/_core/_dtype.py ADDED
@@ -0,0 +1,6 @@
 
 
 
 
 
 
 
1
+ from numpy.core import _dtype
2
+
3
+ _globals = globals()
4
+
5
+ for item in _dtype.__dir__():
6
+ _globals[item] = getattr(_dtype, item)
.venv/lib/python3.11/site-packages/numpy/_core/_dtype_ctypes.py ADDED
@@ -0,0 +1,6 @@
 
 
 
 
 
 
 
1
+ from numpy.core import _dtype_ctypes
2
+
3
+ _globals = globals()
4
+
5
+ for item in _dtype_ctypes.__dir__():
6
+ _globals[item] = getattr(_dtype_ctypes, item)
.venv/lib/python3.11/site-packages/numpy/_core/_internal.py ADDED
@@ -0,0 +1,6 @@
 
 
 
 
 
 
 
1
+ from numpy.core import _internal
2
+
3
+ _globals = globals()
4
+
5
+ for item in _internal.__dir__():
6
+ _globals[item] = getattr(_internal, item)
.venv/lib/python3.11/site-packages/numpy/_core/_multiarray_umath.py ADDED
@@ -0,0 +1,6 @@
 
 
 
 
 
 
 
1
+ from numpy.core import _multiarray_umath
2
+
3
+ _globals = globals()
4
+
5
+ for item in _multiarray_umath.__dir__():
6
+ _globals[item] = getattr(_multiarray_umath, item)
.venv/lib/python3.11/site-packages/numpy/_core/multiarray.py ADDED
@@ -0,0 +1,6 @@
 
 
 
 
 
 
 
1
+ from numpy.core import multiarray
2
+
3
+ _globals = globals()
4
+
5
+ for item in multiarray.__dir__():
6
+ _globals[item] = getattr(multiarray, item)
.venv/lib/python3.11/site-packages/numpy/_core/umath.py ADDED
@@ -0,0 +1,6 @@
 
 
 
 
 
 
 
1
+ from numpy.core import umath
2
+
3
+ _globals = globals()
4
+
5
+ for item in umath.__dir__():
6
+ _globals[item] = getattr(umath, item)
.venv/lib/python3.11/site-packages/numpy/distutils/__pycache__/ccompiler_opt.cpython-311.pyc ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:1f028da28ccdb1a5a6e60c4f0a116f52a11e5d7135c99e75298848c3d5bdbdd1
3
+ size 120311
.venv/lib/python3.11/site-packages/numpy/distutils/__pycache__/misc_util.cpython-311.pyc ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:7a8a1c343739460f44df3f6fa2b7ebbf39191903196c937c6c82a5f412da965f
3
+ size 118777
.venv/lib/python3.11/site-packages/numpy/distutils/__pycache__/system_info.cpython-311.pyc ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:42cdd14962a62a36c736f614fa765b62a87a5c4a148b35e9e0b93ea397a2fd92
3
+ size 158862
.venv/lib/python3.11/site-packages/numpy/distutils/fcompiler/__pycache__/__init__.cpython-311.pyc ADDED
Binary file (48 kB). View file
 
.venv/lib/python3.11/site-packages/numpy/distutils/fcompiler/__pycache__/intel.cpython-311.pyc ADDED
Binary file (8.81 kB). View file
 
.venv/lib/python3.11/site-packages/numpy/distutils/fcompiler/__pycache__/mips.cpython-311.pyc ADDED
Binary file (3.15 kB). View file
 
.venv/lib/python3.11/site-packages/numpy/distutils/fcompiler/__pycache__/none.cpython-311.pyc ADDED
Binary file (1.34 kB). View file
 
.venv/lib/python3.11/site-packages/numpy/distutils/fcompiler/__pycache__/pathf95.cpython-311.pyc ADDED
Binary file (1.8 kB). View file
 
.venv/lib/python3.11/site-packages/numpy/distutils/fcompiler/__pycache__/sun.cpython-311.pyc ADDED
Binary file (2.81 kB). View file
 
.venv/lib/python3.11/site-packages/numpy/ma/API_CHANGES.txt ADDED
@@ -0,0 +1,135 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ .. -*- rest -*-
2
+
3
+ ==================================================
4
+ API changes in the new masked array implementation
5
+ ==================================================
6
+
7
+ Masked arrays are subclasses of ndarray
8
+ ---------------------------------------
9
+
10
+ Contrary to the original implementation, masked arrays are now regular
11
+ ndarrays::
12
+
13
+ >>> x = masked_array([1,2,3],mask=[0,0,1])
14
+ >>> print isinstance(x, numpy.ndarray)
15
+ True
16
+
17
+
18
+ ``_data`` returns a view of the masked array
19
+ --------------------------------------------
20
+
21
+ Masked arrays are composed of a ``_data`` part and a ``_mask``. Accessing the
22
+ ``_data`` part will return a regular ndarray or any of its subclass, depending
23
+ on the initial data::
24
+
25
+ >>> x = masked_array(numpy.matrix([[1,2],[3,4]]),mask=[[0,0],[0,1]])
26
+ >>> print x._data
27
+ [[1 2]
28
+ [3 4]]
29
+ >>> print type(x._data)
30
+ <class 'numpy.matrixlib.defmatrix.matrix'>
31
+
32
+
33
+ In practice, ``_data`` is implemented as a property, not as an attribute.
34
+ Therefore, you cannot access it directly, and some simple tests such as the
35
+ following one will fail::
36
+
37
+ >>>x._data is x._data
38
+ False
39
+
40
+
41
+ ``filled(x)`` can return a subclass of ndarray
42
+ ----------------------------------------------
43
+ The function ``filled(a)`` returns an array of the same type as ``a._data``::
44
+
45
+ >>> x = masked_array(numpy.matrix([[1,2],[3,4]]),mask=[[0,0],[0,1]])
46
+ >>> y = filled(x)
47
+ >>> print type(y)
48
+ <class 'numpy.matrixlib.defmatrix.matrix'>
49
+ >>> print y
50
+ matrix([[ 1, 2],
51
+ [ 3, 999999]])
52
+
53
+
54
+ ``put``, ``putmask`` behave like their ndarray counterparts
55
+ -----------------------------------------------------------
56
+
57
+ Previously, ``putmask`` was used like this::
58
+
59
+ mask = [False,True,True]
60
+ x = array([1,4,7],mask=mask)
61
+ putmask(x,mask,[3])
62
+
63
+ which translated to::
64
+
65
+ x[~mask] = [3]
66
+
67
+ (Note that a ``True``-value in a mask suppresses a value.)
68
+
69
+ In other words, the mask had the same length as ``x``, whereas
70
+ ``values`` had ``sum(~mask)`` elements.
71
+
72
+ Now, the behaviour is similar to that of ``ndarray.putmask``, where
73
+ the mask and the values are both the same length as ``x``, i.e.
74
+
75
+ ::
76
+
77
+ putmask(x,mask,[3,0,0])
78
+
79
+
80
+ ``fill_value`` is a property
81
+ ----------------------------
82
+
83
+ ``fill_value`` is no longer a method, but a property::
84
+
85
+ >>> print x.fill_value
86
+ 999999
87
+
88
+ ``cumsum`` and ``cumprod`` ignore missing values
89
+ ------------------------------------------------
90
+
91
+ Missing values are assumed to be the identity element, i.e. 0 for
92
+ ``cumsum`` and 1 for ``cumprod``::
93
+
94
+ >>> x = N.ma.array([1,2,3,4],mask=[False,True,False,False])
95
+ >>> print x
96
+ [1 -- 3 4]
97
+ >>> print x.cumsum()
98
+ [1 -- 4 8]
99
+ >> print x.cumprod()
100
+ [1 -- 3 12]
101
+
102
+ ``bool(x)`` raises a ValueError
103
+ -------------------------------
104
+
105
+ Masked arrays now behave like regular ``ndarrays``, in that they cannot be
106
+ converted to booleans:
107
+
108
+ ::
109
+
110
+ >>> x = N.ma.array([1,2,3])
111
+ >>> bool(x)
112
+ Traceback (most recent call last):
113
+ File "<stdin>", line 1, in <module>
114
+ ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()
115
+
116
+
117
+ ==================================
118
+ New features (non exhaustive list)
119
+ ==================================
120
+
121
+ ``mr_``
122
+ -------
123
+
124
+ ``mr_`` mimics the behavior of ``r_`` for masked arrays::
125
+
126
+ >>> np.ma.mr_[3,4,5]
127
+ masked_array(data = [3 4 5],
128
+ mask = False,
129
+ fill_value=999999)
130
+
131
+
132
+ ``anom``
133
+ --------
134
+
135
+ The ``anom`` method returns the deviations from the average (anomalies).
.venv/lib/python3.11/site-packages/numpy/ma/LICENSE ADDED
@@ -0,0 +1,24 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ * Copyright (c) 2006, University of Georgia and Pierre G.F. Gerard-Marchant
2
+ * All rights reserved.
3
+ * Redistribution and use in source and binary forms, with or without
4
+ * modification, are permitted provided that the following conditions are met:
5
+ *
6
+ * * Redistributions of source code must retain the above copyright
7
+ * notice, this list of conditions and the following disclaimer.
8
+ * * Redistributions in binary form must reproduce the above copyright
9
+ * notice, this list of conditions and the following disclaimer in the
10
+ * documentation and/or other materials provided with the distribution.
11
+ * * Neither the name of the University of Georgia nor the
12
+ * names of its contributors may be used to endorse or promote products
13
+ * derived from this software without specific prior written permission.
14
+ *
15
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY
16
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
17
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
18
+ * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
19
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
20
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
21
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
22
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
24
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
.venv/lib/python3.11/site-packages/numpy/ma/README.rst ADDED
@@ -0,0 +1,236 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ==================================
2
+ A Guide to Masked Arrays in NumPy
3
+ ==================================
4
+
5
+ .. Contents::
6
+
7
+ See http://www.scipy.org/scipy/numpy/wiki/MaskedArray (dead link)
8
+ for updates of this document.
9
+
10
+
11
+ History
12
+ -------
13
+
14
+ As a regular user of MaskedArray, I (Pierre G.F. Gerard-Marchant) became
15
+ increasingly frustrated with the subclassing of masked arrays (even if
16
+ I can only blame my inexperience). I needed to develop a class of arrays
17
+ that could store some additional information along with numerical values,
18
+ while keeping the possibility for missing data (picture storing a series
19
+ of dates along with measurements, what would later become the `TimeSeries
20
+ Scikit <http://projects.scipy.org/scipy/scikits/wiki/TimeSeries>`__
21
+ (dead link).
22
+
23
+ I started to implement such a class, but then quickly realized that
24
+ any additional information disappeared when processing these subarrays
25
+ (for example, adding a constant value to a subarray would erase its
26
+ dates). I ended up writing the equivalent of *numpy.core.ma* for my
27
+ particular class, ufuncs included. Everything went fine until I needed to
28
+ subclass my new class, when more problems showed up: some attributes of
29
+ the new subclass were lost during processing. I identified the culprit as
30
+ MaskedArray, which returns masked ndarrays when I expected masked
31
+ arrays of my class. I was preparing myself to rewrite *numpy.core.ma*
32
+ when I forced myself to learn how to subclass ndarrays. As I became more
33
+ familiar with the *__new__* and *__array_finalize__* methods,
34
+ I started to wonder why masked arrays were objects, and not ndarrays,
35
+ and whether it wouldn't be more convenient for subclassing if they did
36
+ behave like regular ndarrays.
37
+
38
+ The new *maskedarray* is what I eventually come up with. The
39
+ main differences with the initial *numpy.core.ma* package are
40
+ that MaskedArray is now a subclass of *ndarray* and that the
41
+ *_data* section can now be any subclass of *ndarray*. Apart from a
42
+ couple of issues listed below, the behavior of the new MaskedArray
43
+ class reproduces the old one. Initially the *maskedarray*
44
+ implementation was marginally slower than *numpy.ma* in some areas,
45
+ but work is underway to speed it up; the expectation is that it can be
46
+ made substantially faster than the present *numpy.ma*.
47
+
48
+
49
+ Note that if the subclass has some special methods and
50
+ attributes, they are not propagated to the masked version:
51
+ this would require a modification of the *__getattribute__*
52
+ method (first trying *ndarray.__getattribute__*, then trying
53
+ *self._data.__getattribute__* if an exception is raised in the first
54
+ place), which really slows things down.
55
+
56
+ Main differences
57
+ ----------------
58
+
59
+ * The *_data* part of the masked array can be any subclass of ndarray (but not recarray, cf below).
60
+ * *fill_value* is now a property, not a function.
61
+ * in the majority of cases, the mask is forced to *nomask* when no value is actually masked. A notable exception is when a masked array (with no masked values) has just been unpickled.
62
+ * I got rid of the *share_mask* flag, I never understood its purpose.
63
+ * *put*, *putmask* and *take* now mimic the ndarray methods, to avoid unpleasant surprises. Moreover, *put* and *putmask* both update the mask when needed. * if *a* is a masked array, *bool(a)* raises a *ValueError*, as it does with ndarrays.
64
+ * in the same way, the comparison of two masked arrays is a masked array, not a boolean
65
+ * *filled(a)* returns an array of the same subclass as *a._data*, and no test is performed on whether it is contiguous or not.
66
+ * the mask is always printed, even if it's *nomask*, which makes things easy (for me at least) to remember that a masked array is used.
67
+ * *cumsum* works as if the *_data* array was filled with 0. The mask is preserved, but not updated.
68
+ * *cumprod* works as if the *_data* array was filled with 1. The mask is preserved, but not updated.
69
+
70
+ New features
71
+ ------------
72
+
73
+ This list is non-exhaustive...
74
+
75
+ * the *mr_* function mimics *r_* for masked arrays.
76
+ * the *anom* method returns the anomalies (deviations from the average)
77
+
78
+ Using the new package with numpy.core.ma
79
+ ----------------------------------------
80
+
81
+ I tried to make sure that the new package can understand old masked
82
+ arrays. Unfortunately, there's no upward compatibility.
83
+
84
+ For example:
85
+
86
+ >>> import numpy.core.ma as old_ma
87
+ >>> import maskedarray as new_ma
88
+ >>> x = old_ma.array([1,2,3,4,5], mask=[0,0,1,0,0])
89
+ >>> x
90
+ array(data =
91
+ [ 1 2 999999 4 5],
92
+ mask =
93
+ [False False True False False],
94
+ fill_value=999999)
95
+ >>> y = new_ma.array([1,2,3,4,5], mask=[0,0,1,0,0])
96
+ >>> y
97
+ array(data = [1 2 -- 4 5],
98
+ mask = [False False True False False],
99
+ fill_value=999999)
100
+ >>> x==y
101
+ array(data =
102
+ [True True True True True],
103
+ mask =
104
+ [False False True False False],
105
+ fill_value=?)
106
+ >>> old_ma.getmask(x) == new_ma.getmask(x)
107
+ array([True, True, True, True, True])
108
+ >>> old_ma.getmask(y) == new_ma.getmask(y)
109
+ array([True, True, False, True, True])
110
+ >>> old_ma.getmask(y)
111
+ False
112
+
113
+
114
+ Using maskedarray with matplotlib
115
+ ---------------------------------
116
+
117
+ Starting with matplotlib 0.91.2, the masked array importing will work with
118
+ the maskedarray branch) as well as with earlier versions.
119
+
120
+ By default matplotlib still uses numpy.ma, but there is an rcParams setting
121
+ that you can use to select maskedarray instead. In the matplotlibrc file
122
+ you will find::
123
+
124
+ #maskedarray : False # True to use external maskedarray module
125
+ # instead of numpy.ma; this is a temporary #
126
+ setting for testing maskedarray.
127
+
128
+
129
+ Uncomment and set to True to select maskedarray everywhere.
130
+ Alternatively, you can test a script with maskedarray by using a
131
+ command-line option, e.g.::
132
+
133
+ python simple_plot.py --maskedarray
134
+
135
+
136
+ Masked records
137
+ --------------
138
+
139
+ Like *numpy.core.ma*, the *ndarray*-based implementation
140
+ of MaskedArray is limited when working with records: you can
141
+ mask any record of the array, but not a field in a record. If you
142
+ need this feature, you may want to give the *mrecords* package
143
+ a try (available in the *maskedarray* directory in the scipy
144
+ sandbox). This module defines a new class, *MaskedRecord*. An
145
+ instance of this class accepts a *recarray* as data, and uses two
146
+ masks: the *fieldmask* has as many entries as records in the array,
147
+ each entry with the same fields as a record, but of boolean types:
148
+ they indicate whether the field is masked or not; a record entry
149
+ is flagged as masked in the *mask* array if all the fields are
150
+ masked. A few examples in the file should give you an idea of what
151
+ can be done. Note that *mrecords* is still experimental...
152
+
153
+ Optimizing maskedarray
154
+ ----------------------
155
+
156
+ Should masked arrays be filled before processing or not?
157
+ --------------------------------------------------------
158
+
159
+ In the current implementation, most operations on masked arrays involve
160
+ the following steps:
161
+
162
+ * the input arrays are filled
163
+ * the operation is performed on the filled arrays
164
+ * the mask is set for the results, from the combination of the input masks and the mask corresponding to the domain of the operation.
165
+
166
+ For example, consider the division of two masked arrays::
167
+
168
+ import numpy
169
+ import maskedarray as ma
170
+ x = ma.array([1,2,3,4],mask=[1,0,0,0], dtype=numpy.float_)
171
+ y = ma.array([-1,0,1,2], mask=[0,0,0,1], dtype=numpy.float_)
172
+
173
+ The division of x by y is then computed as::
174
+
175
+ d1 = x.filled(0) # d1 = array([0., 2., 3., 4.])
176
+ d2 = y.filled(1) # array([-1., 0., 1., 1.])
177
+ m = ma.mask_or(ma.getmask(x), ma.getmask(y)) # m =
178
+ array([True,False,False,True])
179
+ dm = ma.divide.domain(d1,d2) # array([False, True, False, False])
180
+ result = (d1/d2).view(MaskedArray) # masked_array([-0. inf, 3., 4.])
181
+ result._mask = logical_or(m, dm)
182
+
183
+ Note that a division by zero takes place. To avoid it, we can consider
184
+ to fill the input arrays, taking the domain mask into account, so that::
185
+
186
+ d1 = x._data.copy() # d1 = array([1., 2., 3., 4.])
187
+ d2 = y._data.copy() # array([-1., 0., 1., 2.])
188
+ dm = ma.divide.domain(d1,d2) # array([False, True, False, False])
189
+ numpy.putmask(d2, dm, 1) # d2 = array([-1., 1., 1., 2.])
190
+ m = ma.mask_or(ma.getmask(x), ma.getmask(y)) # m =
191
+ array([True,False,False,True])
192
+ result = (d1/d2).view(MaskedArray) # masked_array([-1. 0., 3., 2.])
193
+ result._mask = logical_or(m, dm)
194
+
195
+ Note that the *.copy()* is required to avoid updating the inputs with
196
+ *putmask*. The *.filled()* method also involves a *.copy()*.
197
+
198
+ A third possibility consists in avoid filling the arrays::
199
+
200
+ d1 = x._data # d1 = array([1., 2., 3., 4.])
201
+ d2 = y._data # array([-1., 0., 1., 2.])
202
+ dm = ma.divide.domain(d1,d2) # array([False, True, False, False])
203
+ m = ma.mask_or(ma.getmask(x), ma.getmask(y)) # m =
204
+ array([True,False,False,True])
205
+ result = (d1/d2).view(MaskedArray) # masked_array([-1. inf, 3., 2.])
206
+ result._mask = logical_or(m, dm)
207
+
208
+ Note that here again the division by zero takes place.
209
+
210
+ A quick benchmark gives the following results:
211
+
212
+ * *numpy.ma.divide* : 2.69 ms per loop
213
+ * classical division : 2.21 ms per loop
214
+ * division w/ prefilling : 2.34 ms per loop
215
+ * division w/o filling : 1.55 ms per loop
216
+
217
+ So, is it worth filling the arrays beforehand ? Yes, if we are interested
218
+ in avoiding floating-point exceptions that may fill the result with infs
219
+ and nans. No, if we are only interested into speed...
220
+
221
+
222
+ Thanks
223
+ ------
224
+
225
+ I'd like to thank Paul Dubois, Travis Oliphant and Sasha for the
226
+ original masked array package: without you, I would never have started
227
+ that (it might be argued that I shouldn't have anyway, but that's
228
+ another story...). I also wish to extend these thanks to Reggie Dugard
229
+ and Eric Firing for their suggestions and numerous improvements.
230
+
231
+
232
+ Revision notes
233
+ --------------
234
+
235
+ * 08/25/2007 : Creation of this page
236
+ * 01/23/2007 : The package has been moved to the SciPy sandbox, and is regularly updated: please check out your SVN version!
.venv/lib/python3.11/site-packages/numpy/ma/__init__.py ADDED
@@ -0,0 +1,54 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ =============
3
+ Masked Arrays
4
+ =============
5
+
6
+ Arrays sometimes contain invalid or missing data. When doing operations
7
+ on such arrays, we wish to suppress invalid values, which is the purpose masked
8
+ arrays fulfill (an example of typical use is given below).
9
+
10
+ For example, examine the following array:
11
+
12
+ >>> x = np.array([2, 1, 3, np.nan, 5, 2, 3, np.nan])
13
+
14
+ When we try to calculate the mean of the data, the result is undetermined:
15
+
16
+ >>> np.mean(x)
17
+ nan
18
+
19
+ The mean is calculated using roughly ``np.sum(x)/len(x)``, but since
20
+ any number added to ``NaN`` [1]_ produces ``NaN``, this doesn't work. Enter
21
+ masked arrays:
22
+
23
+ >>> m = np.ma.masked_array(x, np.isnan(x))
24
+ >>> m
25
+ masked_array(data = [2.0 1.0 3.0 -- 5.0 2.0 3.0 --],
26
+ mask = [False False False True False False False True],
27
+ fill_value=1e+20)
28
+
29
+ Here, we construct a masked array that suppress all ``NaN`` values. We
30
+ may now proceed to calculate the mean of the other values:
31
+
32
+ >>> np.mean(m)
33
+ 2.6666666666666665
34
+
35
+ .. [1] Not-a-Number, a floating point value that is the result of an
36
+ invalid operation.
37
+
38
+ .. moduleauthor:: Pierre Gerard-Marchant
39
+ .. moduleauthor:: Jarrod Millman
40
+
41
+ """
42
+ from . import core
43
+ from .core import *
44
+
45
+ from . import extras
46
+ from .extras import *
47
+
48
+ __all__ = ['core', 'extras']
49
+ __all__ += core.__all__
50
+ __all__ += extras.__all__
51
+
52
+ from numpy._pytesttester import PytestTester
53
+ test = PytestTester(__name__)
54
+ del PytestTester
.venv/lib/python3.11/site-packages/numpy/ma/__init__.pyi ADDED
@@ -0,0 +1,234 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from numpy._pytesttester import PytestTester
2
+
3
+ from numpy.ma import extras as extras
4
+
5
+ from numpy.ma.core import (
6
+ MAError as MAError,
7
+ MaskError as MaskError,
8
+ MaskType as MaskType,
9
+ MaskedArray as MaskedArray,
10
+ abs as abs,
11
+ absolute as absolute,
12
+ add as add,
13
+ all as all,
14
+ allclose as allclose,
15
+ allequal as allequal,
16
+ alltrue as alltrue,
17
+ amax as amax,
18
+ amin as amin,
19
+ angle as angle,
20
+ anom as anom,
21
+ anomalies as anomalies,
22
+ any as any,
23
+ append as append,
24
+ arange as arange,
25
+ arccos as arccos,
26
+ arccosh as arccosh,
27
+ arcsin as arcsin,
28
+ arcsinh as arcsinh,
29
+ arctan as arctan,
30
+ arctan2 as arctan2,
31
+ arctanh as arctanh,
32
+ argmax as argmax,
33
+ argmin as argmin,
34
+ argsort as argsort,
35
+ around as around,
36
+ array as array,
37
+ asanyarray as asanyarray,
38
+ asarray as asarray,
39
+ bitwise_and as bitwise_and,
40
+ bitwise_or as bitwise_or,
41
+ bitwise_xor as bitwise_xor,
42
+ bool_ as bool_,
43
+ ceil as ceil,
44
+ choose as choose,
45
+ clip as clip,
46
+ common_fill_value as common_fill_value,
47
+ compress as compress,
48
+ compressed as compressed,
49
+ concatenate as concatenate,
50
+ conjugate as conjugate,
51
+ convolve as convolve,
52
+ copy as copy,
53
+ correlate as correlate,
54
+ cos as cos,
55
+ cosh as cosh,
56
+ count as count,
57
+ cumprod as cumprod,
58
+ cumsum as cumsum,
59
+ default_fill_value as default_fill_value,
60
+ diag as diag,
61
+ diagonal as diagonal,
62
+ diff as diff,
63
+ divide as divide,
64
+ empty as empty,
65
+ empty_like as empty_like,
66
+ equal as equal,
67
+ exp as exp,
68
+ expand_dims as expand_dims,
69
+ fabs as fabs,
70
+ filled as filled,
71
+ fix_invalid as fix_invalid,
72
+ flatten_mask as flatten_mask,
73
+ flatten_structured_array as flatten_structured_array,
74
+ floor as floor,
75
+ floor_divide as floor_divide,
76
+ fmod as fmod,
77
+ frombuffer as frombuffer,
78
+ fromflex as fromflex,
79
+ fromfunction as fromfunction,
80
+ getdata as getdata,
81
+ getmask as getmask,
82
+ getmaskarray as getmaskarray,
83
+ greater as greater,
84
+ greater_equal as greater_equal,
85
+ harden_mask as harden_mask,
86
+ hypot as hypot,
87
+ identity as identity,
88
+ ids as ids,
89
+ indices as indices,
90
+ inner as inner,
91
+ innerproduct as innerproduct,
92
+ isMA as isMA,
93
+ isMaskedArray as isMaskedArray,
94
+ is_mask as is_mask,
95
+ is_masked as is_masked,
96
+ isarray as isarray,
97
+ left_shift as left_shift,
98
+ less as less,
99
+ less_equal as less_equal,
100
+ log as log,
101
+ log10 as log10,
102
+ log2 as log2,
103
+ logical_and as logical_and,
104
+ logical_not as logical_not,
105
+ logical_or as logical_or,
106
+ logical_xor as logical_xor,
107
+ make_mask as make_mask,
108
+ make_mask_descr as make_mask_descr,
109
+ make_mask_none as make_mask_none,
110
+ mask_or as mask_or,
111
+ masked as masked,
112
+ masked_array as masked_array,
113
+ masked_equal as masked_equal,
114
+ masked_greater as masked_greater,
115
+ masked_greater_equal as masked_greater_equal,
116
+ masked_inside as masked_inside,
117
+ masked_invalid as masked_invalid,
118
+ masked_less as masked_less,
119
+ masked_less_equal as masked_less_equal,
120
+ masked_not_equal as masked_not_equal,
121
+ masked_object as masked_object,
122
+ masked_outside as masked_outside,
123
+ masked_print_option as masked_print_option,
124
+ masked_singleton as masked_singleton,
125
+ masked_values as masked_values,
126
+ masked_where as masked_where,
127
+ max as max,
128
+ maximum as maximum,
129
+ maximum_fill_value as maximum_fill_value,
130
+ mean as mean,
131
+ min as min,
132
+ minimum as minimum,
133
+ minimum_fill_value as minimum_fill_value,
134
+ mod as mod,
135
+ multiply as multiply,
136
+ mvoid as mvoid,
137
+ ndim as ndim,
138
+ negative as negative,
139
+ nomask as nomask,
140
+ nonzero as nonzero,
141
+ not_equal as not_equal,
142
+ ones as ones,
143
+ outer as outer,
144
+ outerproduct as outerproduct,
145
+ power as power,
146
+ prod as prod,
147
+ product as product,
148
+ ptp as ptp,
149
+ put as put,
150
+ putmask as putmask,
151
+ ravel as ravel,
152
+ remainder as remainder,
153
+ repeat as repeat,
154
+ reshape as reshape,
155
+ resize as resize,
156
+ right_shift as right_shift,
157
+ round as round,
158
+ set_fill_value as set_fill_value,
159
+ shape as shape,
160
+ sin as sin,
161
+ sinh as sinh,
162
+ size as size,
163
+ soften_mask as soften_mask,
164
+ sometrue as sometrue,
165
+ sort as sort,
166
+ sqrt as sqrt,
167
+ squeeze as squeeze,
168
+ std as std,
169
+ subtract as subtract,
170
+ sum as sum,
171
+ swapaxes as swapaxes,
172
+ take as take,
173
+ tan as tan,
174
+ tanh as tanh,
175
+ trace as trace,
176
+ transpose as transpose,
177
+ true_divide as true_divide,
178
+ var as var,
179
+ where as where,
180
+ zeros as zeros,
181
+ )
182
+
183
+ from numpy.ma.extras import (
184
+ apply_along_axis as apply_along_axis,
185
+ apply_over_axes as apply_over_axes,
186
+ atleast_1d as atleast_1d,
187
+ atleast_2d as atleast_2d,
188
+ atleast_3d as atleast_3d,
189
+ average as average,
190
+ clump_masked as clump_masked,
191
+ clump_unmasked as clump_unmasked,
192
+ column_stack as column_stack,
193
+ compress_cols as compress_cols,
194
+ compress_nd as compress_nd,
195
+ compress_rowcols as compress_rowcols,
196
+ compress_rows as compress_rows,
197
+ count_masked as count_masked,
198
+ corrcoef as corrcoef,
199
+ cov as cov,
200
+ diagflat as diagflat,
201
+ dot as dot,
202
+ dstack as dstack,
203
+ ediff1d as ediff1d,
204
+ flatnotmasked_contiguous as flatnotmasked_contiguous,
205
+ flatnotmasked_edges as flatnotmasked_edges,
206
+ hsplit as hsplit,
207
+ hstack as hstack,
208
+ isin as isin,
209
+ in1d as in1d,
210
+ intersect1d as intersect1d,
211
+ mask_cols as mask_cols,
212
+ mask_rowcols as mask_rowcols,
213
+ mask_rows as mask_rows,
214
+ masked_all as masked_all,
215
+ masked_all_like as masked_all_like,
216
+ median as median,
217
+ mr_ as mr_,
218
+ ndenumerate as ndenumerate,
219
+ notmasked_contiguous as notmasked_contiguous,
220
+ notmasked_edges as notmasked_edges,
221
+ polyfit as polyfit,
222
+ row_stack as row_stack,
223
+ setdiff1d as setdiff1d,
224
+ setxor1d as setxor1d,
225
+ stack as stack,
226
+ unique as unique,
227
+ union1d as union1d,
228
+ vander as vander,
229
+ vstack as vstack,
230
+ )
231
+
232
+ __all__: list[str]
233
+ __path__: list[str]
234
+ test: PytestTester
.venv/lib/python3.11/site-packages/numpy/ma/__pycache__/__init__.cpython-311.pyc ADDED
Binary file (1.72 kB). View file
 
.venv/lib/python3.11/site-packages/numpy/ma/__pycache__/extras.cpython-311.pyc ADDED
Binary file (82.1 kB). View file
 
.venv/lib/python3.11/site-packages/numpy/ma/__pycache__/mrecords.cpython-311.pyc ADDED
Binary file (37.9 kB). View file
 
.venv/lib/python3.11/site-packages/numpy/ma/__pycache__/setup.cpython-311.pyc ADDED
Binary file (924 Bytes). View file
 
.venv/lib/python3.11/site-packages/numpy/ma/__pycache__/testutils.cpython-311.pyc ADDED
Binary file (14.6 kB). View file
 
.venv/lib/python3.11/site-packages/numpy/ma/__pycache__/timer_comparison.cpython-311.pyc ADDED
Binary file (28 kB). View file
 
.venv/lib/python3.11/site-packages/numpy/ma/core.py ADDED
The diff for this file is too large to render. See raw diff
 
.venv/lib/python3.11/site-packages/numpy/ma/core.pyi ADDED
@@ -0,0 +1,471 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from collections.abc import Callable
2
+ from typing import Any, TypeVar
3
+ from numpy import ndarray, dtype, float64
4
+
5
+ from numpy import (
6
+ amax as amax,
7
+ amin as amin,
8
+ bool_ as bool_,
9
+ expand_dims as expand_dims,
10
+ clip as clip,
11
+ indices as indices,
12
+ ones_like as ones_like,
13
+ squeeze as squeeze,
14
+ zeros_like as zeros_like,
15
+ )
16
+
17
+ from numpy.lib.function_base import (
18
+ angle as angle,
19
+ )
20
+
21
+ # TODO: Set the `bound` to something more suitable once we
22
+ # have proper shape support
23
+ _ShapeType = TypeVar("_ShapeType", bound=Any)
24
+ _DType_co = TypeVar("_DType_co", bound=dtype[Any], covariant=True)
25
+
26
+ __all__: list[str]
27
+
28
+ MaskType = bool_
29
+ nomask: bool_
30
+
31
+ class MaskedArrayFutureWarning(FutureWarning): ...
32
+ class MAError(Exception): ...
33
+ class MaskError(MAError): ...
34
+
35
+ def default_fill_value(obj): ...
36
+ def minimum_fill_value(obj): ...
37
+ def maximum_fill_value(obj): ...
38
+ def set_fill_value(a, fill_value): ...
39
+ def common_fill_value(a, b): ...
40
+ def filled(a, fill_value=...): ...
41
+ def getdata(a, subok=...): ...
42
+ get_data = getdata
43
+
44
+ def fix_invalid(a, mask=..., copy=..., fill_value=...): ...
45
+
46
+ class _MaskedUFunc:
47
+ f: Any
48
+ __doc__: Any
49
+ __name__: Any
50
+ def __init__(self, ufunc): ...
51
+
52
+ class _MaskedUnaryOperation(_MaskedUFunc):
53
+ fill: Any
54
+ domain: Any
55
+ def __init__(self, mufunc, fill=..., domain=...): ...
56
+ def __call__(self, a, *args, **kwargs): ...
57
+
58
+ class _MaskedBinaryOperation(_MaskedUFunc):
59
+ fillx: Any
60
+ filly: Any
61
+ def __init__(self, mbfunc, fillx=..., filly=...): ...
62
+ def __call__(self, a, b, *args, **kwargs): ...
63
+ def reduce(self, target, axis=..., dtype=...): ...
64
+ def outer(self, a, b): ...
65
+ def accumulate(self, target, axis=...): ...
66
+
67
+ class _DomainedBinaryOperation(_MaskedUFunc):
68
+ domain: Any
69
+ fillx: Any
70
+ filly: Any
71
+ def __init__(self, dbfunc, domain, fillx=..., filly=...): ...
72
+ def __call__(self, a, b, *args, **kwargs): ...
73
+
74
+ exp: _MaskedUnaryOperation
75
+ conjugate: _MaskedUnaryOperation
76
+ sin: _MaskedUnaryOperation
77
+ cos: _MaskedUnaryOperation
78
+ arctan: _MaskedUnaryOperation
79
+ arcsinh: _MaskedUnaryOperation
80
+ sinh: _MaskedUnaryOperation
81
+ cosh: _MaskedUnaryOperation
82
+ tanh: _MaskedUnaryOperation
83
+ abs: _MaskedUnaryOperation
84
+ absolute: _MaskedUnaryOperation
85
+ fabs: _MaskedUnaryOperation
86
+ negative: _MaskedUnaryOperation
87
+ floor: _MaskedUnaryOperation
88
+ ceil: _MaskedUnaryOperation
89
+ around: _MaskedUnaryOperation
90
+ logical_not: _MaskedUnaryOperation
91
+ sqrt: _MaskedUnaryOperation
92
+ log: _MaskedUnaryOperation
93
+ log2: _MaskedUnaryOperation
94
+ log10: _MaskedUnaryOperation
95
+ tan: _MaskedUnaryOperation
96
+ arcsin: _MaskedUnaryOperation
97
+ arccos: _MaskedUnaryOperation
98
+ arccosh: _MaskedUnaryOperation
99
+ arctanh: _MaskedUnaryOperation
100
+
101
+ add: _MaskedBinaryOperation
102
+ subtract: _MaskedBinaryOperation
103
+ multiply: _MaskedBinaryOperation
104
+ arctan2: _MaskedBinaryOperation
105
+ equal: _MaskedBinaryOperation
106
+ not_equal: _MaskedBinaryOperation
107
+ less_equal: _MaskedBinaryOperation
108
+ greater_equal: _MaskedBinaryOperation
109
+ less: _MaskedBinaryOperation
110
+ greater: _MaskedBinaryOperation
111
+ logical_and: _MaskedBinaryOperation
112
+ alltrue: _MaskedBinaryOperation
113
+ logical_or: _MaskedBinaryOperation
114
+ sometrue: Callable[..., Any]
115
+ logical_xor: _MaskedBinaryOperation
116
+ bitwise_and: _MaskedBinaryOperation
117
+ bitwise_or: _MaskedBinaryOperation
118
+ bitwise_xor: _MaskedBinaryOperation
119
+ hypot: _MaskedBinaryOperation
120
+ divide: _MaskedBinaryOperation
121
+ true_divide: _MaskedBinaryOperation
122
+ floor_divide: _MaskedBinaryOperation
123
+ remainder: _MaskedBinaryOperation
124
+ fmod: _MaskedBinaryOperation
125
+ mod: _MaskedBinaryOperation
126
+
127
+ def make_mask_descr(ndtype): ...
128
+ def getmask(a): ...
129
+ get_mask = getmask
130
+
131
+ def getmaskarray(arr): ...
132
+ def is_mask(m): ...
133
+ def make_mask(m, copy=..., shrink=..., dtype=...): ...
134
+ def make_mask_none(newshape, dtype=...): ...
135
+ def mask_or(m1, m2, copy=..., shrink=...): ...
136
+ def flatten_mask(mask): ...
137
+ def masked_where(condition, a, copy=...): ...
138
+ def masked_greater(x, value, copy=...): ...
139
+ def masked_greater_equal(x, value, copy=...): ...
140
+ def masked_less(x, value, copy=...): ...
141
+ def masked_less_equal(x, value, copy=...): ...
142
+ def masked_not_equal(x, value, copy=...): ...
143
+ def masked_equal(x, value, copy=...): ...
144
+ def masked_inside(x, v1, v2, copy=...): ...
145
+ def masked_outside(x, v1, v2, copy=...): ...
146
+ def masked_object(x, value, copy=..., shrink=...): ...
147
+ def masked_values(x, value, rtol=..., atol=..., copy=..., shrink=...): ...
148
+ def masked_invalid(a, copy=...): ...
149
+
150
+ class _MaskedPrintOption:
151
+ def __init__(self, display): ...
152
+ def display(self): ...
153
+ def set_display(self, s): ...
154
+ def enabled(self): ...
155
+ def enable(self, shrink=...): ...
156
+
157
+ masked_print_option: _MaskedPrintOption
158
+
159
+ def flatten_structured_array(a): ...
160
+
161
+ class MaskedIterator:
162
+ ma: Any
163
+ dataiter: Any
164
+ maskiter: Any
165
+ def __init__(self, ma): ...
166
+ def __iter__(self): ...
167
+ def __getitem__(self, indx): ...
168
+ def __setitem__(self, index, value): ...
169
+ def __next__(self): ...
170
+
171
+ class MaskedArray(ndarray[_ShapeType, _DType_co]):
172
+ __array_priority__: Any
173
+ def __new__(cls, data=..., mask=..., dtype=..., copy=..., subok=..., ndmin=..., fill_value=..., keep_mask=..., hard_mask=..., shrink=..., order=...): ...
174
+ def __array_finalize__(self, obj): ...
175
+ def __array_wrap__(self, obj, context=...): ...
176
+ def view(self, dtype=..., type=..., fill_value=...): ...
177
+ def __getitem__(self, indx): ...
178
+ def __setitem__(self, indx, value): ...
179
+ @property
180
+ def dtype(self): ...
181
+ @dtype.setter
182
+ def dtype(self, dtype): ...
183
+ @property
184
+ def shape(self): ...
185
+ @shape.setter
186
+ def shape(self, shape): ...
187
+ def __setmask__(self, mask, copy=...): ...
188
+ @property
189
+ def mask(self): ...
190
+ @mask.setter
191
+ def mask(self, value): ...
192
+ @property
193
+ def recordmask(self): ...
194
+ @recordmask.setter
195
+ def recordmask(self, mask): ...
196
+ def harden_mask(self): ...
197
+ def soften_mask(self): ...
198
+ @property
199
+ def hardmask(self): ...
200
+ def unshare_mask(self): ...
201
+ @property
202
+ def sharedmask(self): ...
203
+ def shrink_mask(self): ...
204
+ @property
205
+ def baseclass(self): ...
206
+ data: Any
207
+ @property
208
+ def flat(self): ...
209
+ @flat.setter
210
+ def flat(self, value): ...
211
+ @property
212
+ def fill_value(self): ...
213
+ @fill_value.setter
214
+ def fill_value(self, value=...): ...
215
+ get_fill_value: Any
216
+ set_fill_value: Any
217
+ def filled(self, fill_value=...): ...
218
+ def compressed(self): ...
219
+ def compress(self, condition, axis=..., out=...): ...
220
+ def __eq__(self, other): ...
221
+ def __ne__(self, other): ...
222
+ def __ge__(self, other): ...
223
+ def __gt__(self, other): ...
224
+ def __le__(self, other): ...
225
+ def __lt__(self, other): ...
226
+ def __add__(self, other): ...
227
+ def __radd__(self, other): ...
228
+ def __sub__(self, other): ...
229
+ def __rsub__(self, other): ...
230
+ def __mul__(self, other): ...
231
+ def __rmul__(self, other): ...
232
+ def __div__(self, other): ...
233
+ def __truediv__(self, other): ...
234
+ def __rtruediv__(self, other): ...
235
+ def __floordiv__(self, other): ...
236
+ def __rfloordiv__(self, other): ...
237
+ def __pow__(self, other): ...
238
+ def __rpow__(self, other): ...
239
+ def __iadd__(self, other): ...
240
+ def __isub__(self, other): ...
241
+ def __imul__(self, other): ...
242
+ def __idiv__(self, other): ...
243
+ def __ifloordiv__(self, other): ...
244
+ def __itruediv__(self, other): ...
245
+ def __ipow__(self, other): ...
246
+ def __float__(self): ...
247
+ def __int__(self): ...
248
+ @property # type: ignore[misc]
249
+ def imag(self): ...
250
+ get_imag: Any
251
+ @property # type: ignore[misc]
252
+ def real(self): ...
253
+ get_real: Any
254
+ def count(self, axis=..., keepdims=...): ...
255
+ def ravel(self, order=...): ...
256
+ def reshape(self, *s, **kwargs): ...
257
+ def resize(self, newshape, refcheck=..., order=...): ...
258
+ def put(self, indices, values, mode=...): ...
259
+ def ids(self): ...
260
+ def iscontiguous(self): ...
261
+ def all(self, axis=..., out=..., keepdims=...): ...
262
+ def any(self, axis=..., out=..., keepdims=...): ...
263
+ def nonzero(self): ...
264
+ def trace(self, offset=..., axis1=..., axis2=..., dtype=..., out=...): ...
265
+ def dot(self, b, out=..., strict=...): ...
266
+ def sum(self, axis=..., dtype=..., out=..., keepdims=...): ...
267
+ def cumsum(self, axis=..., dtype=..., out=...): ...
268
+ def prod(self, axis=..., dtype=..., out=..., keepdims=...): ...
269
+ product: Any
270
+ def cumprod(self, axis=..., dtype=..., out=...): ...
271
+ def mean(self, axis=..., dtype=..., out=..., keepdims=...): ...
272
+ def anom(self, axis=..., dtype=...): ...
273
+ def var(self, axis=..., dtype=..., out=..., ddof=..., keepdims=...): ...
274
+ def std(self, axis=..., dtype=..., out=..., ddof=..., keepdims=...): ...
275
+ def round(self, decimals=..., out=...): ...
276
+ def argsort(self, axis=..., kind=..., order=..., endwith=..., fill_value=...): ...
277
+ def argmin(self, axis=..., fill_value=..., out=..., *, keepdims=...): ...
278
+ def argmax(self, axis=..., fill_value=..., out=..., *, keepdims=...): ...
279
+ def sort(self, axis=..., kind=..., order=..., endwith=..., fill_value=...): ...
280
+ def min(self, axis=..., out=..., fill_value=..., keepdims=...): ...
281
+ # NOTE: deprecated
282
+ # def tostring(self, fill_value=..., order=...): ...
283
+ def max(self, axis=..., out=..., fill_value=..., keepdims=...): ...
284
+ def ptp(self, axis=..., out=..., fill_value=..., keepdims=...): ...
285
+ def partition(self, *args, **kwargs): ...
286
+ def argpartition(self, *args, **kwargs): ...
287
+ def take(self, indices, axis=..., out=..., mode=...): ...
288
+ copy: Any
289
+ diagonal: Any
290
+ flatten: Any
291
+ repeat: Any
292
+ squeeze: Any
293
+ swapaxes: Any
294
+ T: Any
295
+ transpose: Any
296
+ def tolist(self, fill_value=...): ...
297
+ def tobytes(self, fill_value=..., order=...): ...
298
+ def tofile(self, fid, sep=..., format=...): ...
299
+ def toflex(self): ...
300
+ torecords: Any
301
+ def __reduce__(self): ...
302
+ def __deepcopy__(self, memo=...): ...
303
+
304
+ class mvoid(MaskedArray[_ShapeType, _DType_co]):
305
+ def __new__(
306
+ self,
307
+ data,
308
+ mask=...,
309
+ dtype=...,
310
+ fill_value=...,
311
+ hardmask=...,
312
+ copy=...,
313
+ subok=...,
314
+ ): ...
315
+ def __getitem__(self, indx): ...
316
+ def __setitem__(self, indx, value): ...
317
+ def __iter__(self): ...
318
+ def __len__(self): ...
319
+ def filled(self, fill_value=...): ...
320
+ def tolist(self): ...
321
+
322
+ def isMaskedArray(x): ...
323
+ isarray = isMaskedArray
324
+ isMA = isMaskedArray
325
+
326
+ # 0D float64 array
327
+ class MaskedConstant(MaskedArray[Any, dtype[float64]]):
328
+ def __new__(cls): ...
329
+ __class__: Any
330
+ def __array_finalize__(self, obj): ...
331
+ def __array_prepare__(self, obj, context=...): ...
332
+ def __array_wrap__(self, obj, context=...): ...
333
+ def __format__(self, format_spec): ...
334
+ def __reduce__(self): ...
335
+ def __iop__(self, other): ...
336
+ __iadd__: Any
337
+ __isub__: Any
338
+ __imul__: Any
339
+ __ifloordiv__: Any
340
+ __itruediv__: Any
341
+ __ipow__: Any
342
+ def copy(self, *args, **kwargs): ...
343
+ def __copy__(self): ...
344
+ def __deepcopy__(self, memo): ...
345
+ def __setattr__(self, attr, value): ...
346
+
347
+ masked: MaskedConstant
348
+ masked_singleton: MaskedConstant
349
+ masked_array = MaskedArray
350
+
351
+ def array(
352
+ data,
353
+ dtype=...,
354
+ copy=...,
355
+ order=...,
356
+ mask=...,
357
+ fill_value=...,
358
+ keep_mask=...,
359
+ hard_mask=...,
360
+ shrink=...,
361
+ subok=...,
362
+ ndmin=...,
363
+ ): ...
364
+ def is_masked(x): ...
365
+
366
+ class _extrema_operation(_MaskedUFunc):
367
+ compare: Any
368
+ fill_value_func: Any
369
+ def __init__(self, ufunc, compare, fill_value): ...
370
+ # NOTE: in practice `b` has a default value, but users should
371
+ # explicitly provide a value here as the default is deprecated
372
+ def __call__(self, a, b): ...
373
+ def reduce(self, target, axis=...): ...
374
+ def outer(self, a, b): ...
375
+
376
+ def min(obj, axis=..., out=..., fill_value=..., keepdims=...): ...
377
+ def max(obj, axis=..., out=..., fill_value=..., keepdims=...): ...
378
+ def ptp(obj, axis=..., out=..., fill_value=..., keepdims=...): ...
379
+
380
+ class _frommethod:
381
+ __name__: Any
382
+ __doc__: Any
383
+ reversed: Any
384
+ def __init__(self, methodname, reversed=...): ...
385
+ def getdoc(self): ...
386
+ def __call__(self, a, *args, **params): ...
387
+
388
+ all: _frommethod
389
+ anomalies: _frommethod
390
+ anom: _frommethod
391
+ any: _frommethod
392
+ compress: _frommethod
393
+ cumprod: _frommethod
394
+ cumsum: _frommethod
395
+ copy: _frommethod
396
+ diagonal: _frommethod
397
+ harden_mask: _frommethod
398
+ ids: _frommethod
399
+ mean: _frommethod
400
+ nonzero: _frommethod
401
+ prod: _frommethod
402
+ product: _frommethod
403
+ ravel: _frommethod
404
+ repeat: _frommethod
405
+ soften_mask: _frommethod
406
+ std: _frommethod
407
+ sum: _frommethod
408
+ swapaxes: _frommethod
409
+ trace: _frommethod
410
+ var: _frommethod
411
+ count: _frommethod
412
+ argmin: _frommethod
413
+ argmax: _frommethod
414
+
415
+ minimum: _extrema_operation
416
+ maximum: _extrema_operation
417
+
418
+ def take(a, indices, axis=..., out=..., mode=...): ...
419
+ def power(a, b, third=...): ...
420
+ def argsort(a, axis=..., kind=..., order=..., endwith=..., fill_value=...): ...
421
+ def sort(a, axis=..., kind=..., order=..., endwith=..., fill_value=...): ...
422
+ def compressed(x): ...
423
+ def concatenate(arrays, axis=...): ...
424
+ def diag(v, k=...): ...
425
+ def left_shift(a, n): ...
426
+ def right_shift(a, n): ...
427
+ def put(a, indices, values, mode=...): ...
428
+ def putmask(a, mask, values): ...
429
+ def transpose(a, axes=...): ...
430
+ def reshape(a, new_shape, order=...): ...
431
+ def resize(x, new_shape): ...
432
+ def ndim(obj): ...
433
+ def shape(obj): ...
434
+ def size(obj, axis=...): ...
435
+ def diff(a, /, n=..., axis=..., prepend=..., append=...): ...
436
+ def where(condition, x=..., y=...): ...
437
+ def choose(indices, choices, out=..., mode=...): ...
438
+ def round(a, decimals=..., out=...): ...
439
+
440
+ def inner(a, b): ...
441
+ innerproduct = inner
442
+
443
+ def outer(a, b): ...
444
+ outerproduct = outer
445
+
446
+ def correlate(a, v, mode=..., propagate_mask=...): ...
447
+ def convolve(a, v, mode=..., propagate_mask=...): ...
448
+ def allequal(a, b, fill_value=...): ...
449
+ def allclose(a, b, masked_equal=..., rtol=..., atol=...): ...
450
+ def asarray(a, dtype=..., order=...): ...
451
+ def asanyarray(a, dtype=...): ...
452
+ def fromflex(fxarray): ...
453
+
454
+ class _convert2ma:
455
+ __doc__: Any
456
+ def __init__(self, funcname, params=...): ...
457
+ def getdoc(self): ...
458
+ def __call__(self, *args, **params): ...
459
+
460
+ arange: _convert2ma
461
+ empty: _convert2ma
462
+ empty_like: _convert2ma
463
+ frombuffer: _convert2ma
464
+ fromfunction: _convert2ma
465
+ identity: _convert2ma
466
+ ones: _convert2ma
467
+ zeros: _convert2ma
468
+
469
+ def append(a, b, axis=...): ...
470
+ def dot(a, b, strict=..., out=...): ...
471
+ def mask_rowcols(a, axis=...): ...
.venv/lib/python3.11/site-packages/numpy/ma/extras.py ADDED
@@ -0,0 +1,2133 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ Masked arrays add-ons.
3
+
4
+ A collection of utilities for `numpy.ma`.
5
+
6
+ :author: Pierre Gerard-Marchant
7
+ :contact: pierregm_at_uga_dot_edu
8
+ :version: $Id: extras.py 3473 2007-10-29 15:18:13Z jarrod.millman $
9
+
10
+ """
11
+ __all__ = [
12
+ 'apply_along_axis', 'apply_over_axes', 'atleast_1d', 'atleast_2d',
13
+ 'atleast_3d', 'average', 'clump_masked', 'clump_unmasked', 'column_stack',
14
+ 'compress_cols', 'compress_nd', 'compress_rowcols', 'compress_rows',
15
+ 'count_masked', 'corrcoef', 'cov', 'diagflat', 'dot', 'dstack', 'ediff1d',
16
+ 'flatnotmasked_contiguous', 'flatnotmasked_edges', 'hsplit', 'hstack',
17
+ 'isin', 'in1d', 'intersect1d', 'mask_cols', 'mask_rowcols', 'mask_rows',
18
+ 'masked_all', 'masked_all_like', 'median', 'mr_', 'ndenumerate',
19
+ 'notmasked_contiguous', 'notmasked_edges', 'polyfit', 'row_stack',
20
+ 'setdiff1d', 'setxor1d', 'stack', 'unique', 'union1d', 'vander', 'vstack',
21
+ ]
22
+
23
+ import itertools
24
+ import warnings
25
+
26
+ from . import core as ma
27
+ from .core import (
28
+ MaskedArray, MAError, add, array, asarray, concatenate, filled, count,
29
+ getmask, getmaskarray, make_mask_descr, masked, masked_array, mask_or,
30
+ nomask, ones, sort, zeros, getdata, get_masked_subclass, dot
31
+ )
32
+
33
+ import numpy as np
34
+ from numpy import ndarray, array as nxarray
35
+ from numpy.core.multiarray import normalize_axis_index
36
+ from numpy.core.numeric import normalize_axis_tuple
37
+ from numpy.lib.function_base import _ureduce
38
+ from numpy.lib.index_tricks import AxisConcatenator
39
+
40
+
41
+ def issequence(seq):
42
+ """
43
+ Is seq a sequence (ndarray, list or tuple)?
44
+
45
+ """
46
+ return isinstance(seq, (ndarray, tuple, list))
47
+
48
+
49
+ def count_masked(arr, axis=None):
50
+ """
51
+ Count the number of masked elements along the given axis.
52
+
53
+ Parameters
54
+ ----------
55
+ arr : array_like
56
+ An array with (possibly) masked elements.
57
+ axis : int, optional
58
+ Axis along which to count. If None (default), a flattened
59
+ version of the array is used.
60
+
61
+ Returns
62
+ -------
63
+ count : int, ndarray
64
+ The total number of masked elements (axis=None) or the number
65
+ of masked elements along each slice of the given axis.
66
+
67
+ See Also
68
+ --------
69
+ MaskedArray.count : Count non-masked elements.
70
+
71
+ Examples
72
+ --------
73
+ >>> import numpy.ma as ma
74
+ >>> a = np.arange(9).reshape((3,3))
75
+ >>> a = ma.array(a)
76
+ >>> a[1, 0] = ma.masked
77
+ >>> a[1, 2] = ma.masked
78
+ >>> a[2, 1] = ma.masked
79
+ >>> a
80
+ masked_array(
81
+ data=[[0, 1, 2],
82
+ [--, 4, --],
83
+ [6, --, 8]],
84
+ mask=[[False, False, False],
85
+ [ True, False, True],
86
+ [False, True, False]],
87
+ fill_value=999999)
88
+ >>> ma.count_masked(a)
89
+ 3
90
+
91
+ When the `axis` keyword is used an array is returned.
92
+
93
+ >>> ma.count_masked(a, axis=0)
94
+ array([1, 1, 1])
95
+ >>> ma.count_masked(a, axis=1)
96
+ array([0, 2, 1])
97
+
98
+ """
99
+ m = getmaskarray(arr)
100
+ return m.sum(axis)
101
+
102
+
103
+ def masked_all(shape, dtype=float):
104
+ """
105
+ Empty masked array with all elements masked.
106
+
107
+ Return an empty masked array of the given shape and dtype, where all the
108
+ data are masked.
109
+
110
+ Parameters
111
+ ----------
112
+ shape : int or tuple of ints
113
+ Shape of the required MaskedArray, e.g., ``(2, 3)`` or ``2``.
114
+ dtype : dtype, optional
115
+ Data type of the output.
116
+
117
+ Returns
118
+ -------
119
+ a : MaskedArray
120
+ A masked array with all data masked.
121
+
122
+ See Also
123
+ --------
124
+ masked_all_like : Empty masked array modelled on an existing array.
125
+
126
+ Examples
127
+ --------
128
+ >>> import numpy.ma as ma
129
+ >>> ma.masked_all((3, 3))
130
+ masked_array(
131
+ data=[[--, --, --],
132
+ [--, --, --],
133
+ [--, --, --]],
134
+ mask=[[ True, True, True],
135
+ [ True, True, True],
136
+ [ True, True, True]],
137
+ fill_value=1e+20,
138
+ dtype=float64)
139
+
140
+ The `dtype` parameter defines the underlying data type.
141
+
142
+ >>> a = ma.masked_all((3, 3))
143
+ >>> a.dtype
144
+ dtype('float64')
145
+ >>> a = ma.masked_all((3, 3), dtype=np.int32)
146
+ >>> a.dtype
147
+ dtype('int32')
148
+
149
+ """
150
+ a = masked_array(np.empty(shape, dtype),
151
+ mask=np.ones(shape, make_mask_descr(dtype)))
152
+ return a
153
+
154
+
155
+ def masked_all_like(arr):
156
+ """
157
+ Empty masked array with the properties of an existing array.
158
+
159
+ Return an empty masked array of the same shape and dtype as
160
+ the array `arr`, where all the data are masked.
161
+
162
+ Parameters
163
+ ----------
164
+ arr : ndarray
165
+ An array describing the shape and dtype of the required MaskedArray.
166
+
167
+ Returns
168
+ -------
169
+ a : MaskedArray
170
+ A masked array with all data masked.
171
+
172
+ Raises
173
+ ------
174
+ AttributeError
175
+ If `arr` doesn't have a shape attribute (i.e. not an ndarray)
176
+
177
+ See Also
178
+ --------
179
+ masked_all : Empty masked array with all elements masked.
180
+
181
+ Examples
182
+ --------
183
+ >>> import numpy.ma as ma
184
+ >>> arr = np.zeros((2, 3), dtype=np.float32)
185
+ >>> arr
186
+ array([[0., 0., 0.],
187
+ [0., 0., 0.]], dtype=float32)
188
+ >>> ma.masked_all_like(arr)
189
+ masked_array(
190
+ data=[[--, --, --],
191
+ [--, --, --]],
192
+ mask=[[ True, True, True],
193
+ [ True, True, True]],
194
+ fill_value=1e+20,
195
+ dtype=float32)
196
+
197
+ The dtype of the masked array matches the dtype of `arr`.
198
+
199
+ >>> arr.dtype
200
+ dtype('float32')
201
+ >>> ma.masked_all_like(arr).dtype
202
+ dtype('float32')
203
+
204
+ """
205
+ a = np.empty_like(arr).view(MaskedArray)
206
+ a._mask = np.ones(a.shape, dtype=make_mask_descr(a.dtype))
207
+ return a
208
+
209
+
210
+ #####--------------------------------------------------------------------------
211
+ #---- --- Standard functions ---
212
+ #####--------------------------------------------------------------------------
213
+ class _fromnxfunction:
214
+ """
215
+ Defines a wrapper to adapt NumPy functions to masked arrays.
216
+
217
+
218
+ An instance of `_fromnxfunction` can be called with the same parameters
219
+ as the wrapped NumPy function. The docstring of `newfunc` is adapted from
220
+ the wrapped function as well, see `getdoc`.
221
+
222
+ This class should not be used directly. Instead, one of its extensions that
223
+ provides support for a specific type of input should be used.
224
+
225
+ Parameters
226
+ ----------
227
+ funcname : str
228
+ The name of the function to be adapted. The function should be
229
+ in the NumPy namespace (i.e. ``np.funcname``).
230
+
231
+ """
232
+
233
+ def __init__(self, funcname):
234
+ self.__name__ = funcname
235
+ self.__doc__ = self.getdoc()
236
+
237
+ def getdoc(self):
238
+ """
239
+ Retrieve the docstring and signature from the function.
240
+
241
+ The ``__doc__`` attribute of the function is used as the docstring for
242
+ the new masked array version of the function. A note on application
243
+ of the function to the mask is appended.
244
+
245
+ Parameters
246
+ ----------
247
+ None
248
+
249
+ """
250
+ npfunc = getattr(np, self.__name__, None)
251
+ doc = getattr(npfunc, '__doc__', None)
252
+ if doc:
253
+ sig = self.__name__ + ma.get_object_signature(npfunc)
254
+ doc = ma.doc_note(doc, "The function is applied to both the _data "
255
+ "and the _mask, if any.")
256
+ return '\n\n'.join((sig, doc))
257
+ return
258
+
259
+ def __call__(self, *args, **params):
260
+ pass
261
+
262
+
263
+ class _fromnxfunction_single(_fromnxfunction):
264
+ """
265
+ A version of `_fromnxfunction` that is called with a single array
266
+ argument followed by auxiliary args that are passed verbatim for
267
+ both the data and mask calls.
268
+ """
269
+ def __call__(self, x, *args, **params):
270
+ func = getattr(np, self.__name__)
271
+ if isinstance(x, ndarray):
272
+ _d = func(x.__array__(), *args, **params)
273
+ _m = func(getmaskarray(x), *args, **params)
274
+ return masked_array(_d, mask=_m)
275
+ else:
276
+ _d = func(np.asarray(x), *args, **params)
277
+ _m = func(getmaskarray(x), *args, **params)
278
+ return masked_array(_d, mask=_m)
279
+
280
+
281
+ class _fromnxfunction_seq(_fromnxfunction):
282
+ """
283
+ A version of `_fromnxfunction` that is called with a single sequence
284
+ of arrays followed by auxiliary args that are passed verbatim for
285
+ both the data and mask calls.
286
+ """
287
+ def __call__(self, x, *args, **params):
288
+ func = getattr(np, self.__name__)
289
+ _d = func(tuple([np.asarray(a) for a in x]), *args, **params)
290
+ _m = func(tuple([getmaskarray(a) for a in x]), *args, **params)
291
+ return masked_array(_d, mask=_m)
292
+
293
+
294
+ class _fromnxfunction_args(_fromnxfunction):
295
+ """
296
+ A version of `_fromnxfunction` that is called with multiple array
297
+ arguments. The first non-array-like input marks the beginning of the
298
+ arguments that are passed verbatim for both the data and mask calls.
299
+ Array arguments are processed independently and the results are
300
+ returned in a list. If only one array is found, the return value is
301
+ just the processed array instead of a list.
302
+ """
303
+ def __call__(self, *args, **params):
304
+ func = getattr(np, self.__name__)
305
+ arrays = []
306
+ args = list(args)
307
+ while len(args) > 0 and issequence(args[0]):
308
+ arrays.append(args.pop(0))
309
+ res = []
310
+ for x in arrays:
311
+ _d = func(np.asarray(x), *args, **params)
312
+ _m = func(getmaskarray(x), *args, **params)
313
+ res.append(masked_array(_d, mask=_m))
314
+ if len(arrays) == 1:
315
+ return res[0]
316
+ return res
317
+
318
+
319
+ class _fromnxfunction_allargs(_fromnxfunction):
320
+ """
321
+ A version of `_fromnxfunction` that is called with multiple array
322
+ arguments. Similar to `_fromnxfunction_args` except that all args
323
+ are converted to arrays even if they are not so already. This makes
324
+ it possible to process scalars as 1-D arrays. Only keyword arguments
325
+ are passed through verbatim for the data and mask calls. Arrays
326
+ arguments are processed independently and the results are returned
327
+ in a list. If only one arg is present, the return value is just the
328
+ processed array instead of a list.
329
+ """
330
+ def __call__(self, *args, **params):
331
+ func = getattr(np, self.__name__)
332
+ res = []
333
+ for x in args:
334
+ _d = func(np.asarray(x), **params)
335
+ _m = func(getmaskarray(x), **params)
336
+ res.append(masked_array(_d, mask=_m))
337
+ if len(args) == 1:
338
+ return res[0]
339
+ return res
340
+
341
+
342
+ atleast_1d = _fromnxfunction_allargs('atleast_1d')
343
+ atleast_2d = _fromnxfunction_allargs('atleast_2d')
344
+ atleast_3d = _fromnxfunction_allargs('atleast_3d')
345
+
346
+ vstack = row_stack = _fromnxfunction_seq('vstack')
347
+ hstack = _fromnxfunction_seq('hstack')
348
+ column_stack = _fromnxfunction_seq('column_stack')
349
+ dstack = _fromnxfunction_seq('dstack')
350
+ stack = _fromnxfunction_seq('stack')
351
+
352
+ hsplit = _fromnxfunction_single('hsplit')
353
+
354
+ diagflat = _fromnxfunction_single('diagflat')
355
+
356
+
357
+ #####--------------------------------------------------------------------------
358
+ #----
359
+ #####--------------------------------------------------------------------------
360
+ def flatten_inplace(seq):
361
+ """Flatten a sequence in place."""
362
+ k = 0
363
+ while (k != len(seq)):
364
+ while hasattr(seq[k], '__iter__'):
365
+ seq[k:(k + 1)] = seq[k]
366
+ k += 1
367
+ return seq
368
+
369
+
370
+ def apply_along_axis(func1d, axis, arr, *args, **kwargs):
371
+ """
372
+ (This docstring should be overwritten)
373
+ """
374
+ arr = array(arr, copy=False, subok=True)
375
+ nd = arr.ndim
376
+ axis = normalize_axis_index(axis, nd)
377
+ ind = [0] * (nd - 1)
378
+ i = np.zeros(nd, 'O')
379
+ indlist = list(range(nd))
380
+ indlist.remove(axis)
381
+ i[axis] = slice(None, None)
382
+ outshape = np.asarray(arr.shape).take(indlist)
383
+ i.put(indlist, ind)
384
+ res = func1d(arr[tuple(i.tolist())], *args, **kwargs)
385
+ # if res is a number, then we have a smaller output array
386
+ asscalar = np.isscalar(res)
387
+ if not asscalar:
388
+ try:
389
+ len(res)
390
+ except TypeError:
391
+ asscalar = True
392
+ # Note: we shouldn't set the dtype of the output from the first result
393
+ # so we force the type to object, and build a list of dtypes. We'll
394
+ # just take the largest, to avoid some downcasting
395
+ dtypes = []
396
+ if asscalar:
397
+ dtypes.append(np.asarray(res).dtype)
398
+ outarr = zeros(outshape, object)
399
+ outarr[tuple(ind)] = res
400
+ Ntot = np.prod(outshape)
401
+ k = 1
402
+ while k < Ntot:
403
+ # increment the index
404
+ ind[-1] += 1
405
+ n = -1
406
+ while (ind[n] >= outshape[n]) and (n > (1 - nd)):
407
+ ind[n - 1] += 1
408
+ ind[n] = 0
409
+ n -= 1
410
+ i.put(indlist, ind)
411
+ res = func1d(arr[tuple(i.tolist())], *args, **kwargs)
412
+ outarr[tuple(ind)] = res
413
+ dtypes.append(asarray(res).dtype)
414
+ k += 1
415
+ else:
416
+ res = array(res, copy=False, subok=True)
417
+ j = i.copy()
418
+ j[axis] = ([slice(None, None)] * res.ndim)
419
+ j.put(indlist, ind)
420
+ Ntot = np.prod(outshape)
421
+ holdshape = outshape
422
+ outshape = list(arr.shape)
423
+ outshape[axis] = res.shape
424
+ dtypes.append(asarray(res).dtype)
425
+ outshape = flatten_inplace(outshape)
426
+ outarr = zeros(outshape, object)
427
+ outarr[tuple(flatten_inplace(j.tolist()))] = res
428
+ k = 1
429
+ while k < Ntot:
430
+ # increment the index
431
+ ind[-1] += 1
432
+ n = -1
433
+ while (ind[n] >= holdshape[n]) and (n > (1 - nd)):
434
+ ind[n - 1] += 1
435
+ ind[n] = 0
436
+ n -= 1
437
+ i.put(indlist, ind)
438
+ j.put(indlist, ind)
439
+ res = func1d(arr[tuple(i.tolist())], *args, **kwargs)
440
+ outarr[tuple(flatten_inplace(j.tolist()))] = res
441
+ dtypes.append(asarray(res).dtype)
442
+ k += 1
443
+ max_dtypes = np.dtype(np.asarray(dtypes).max())
444
+ if not hasattr(arr, '_mask'):
445
+ result = np.asarray(outarr, dtype=max_dtypes)
446
+ else:
447
+ result = asarray(outarr, dtype=max_dtypes)
448
+ result.fill_value = ma.default_fill_value(result)
449
+ return result
450
+ apply_along_axis.__doc__ = np.apply_along_axis.__doc__
451
+
452
+
453
+ def apply_over_axes(func, a, axes):
454
+ """
455
+ (This docstring will be overwritten)
456
+ """
457
+ val = asarray(a)
458
+ N = a.ndim
459
+ if array(axes).ndim == 0:
460
+ axes = (axes,)
461
+ for axis in axes:
462
+ if axis < 0:
463
+ axis = N + axis
464
+ args = (val, axis)
465
+ res = func(*args)
466
+ if res.ndim == val.ndim:
467
+ val = res
468
+ else:
469
+ res = ma.expand_dims(res, axis)
470
+ if res.ndim == val.ndim:
471
+ val = res
472
+ else:
473
+ raise ValueError("function is not returning "
474
+ "an array of the correct shape")
475
+ return val
476
+
477
+
478
+ if apply_over_axes.__doc__ is not None:
479
+ apply_over_axes.__doc__ = np.apply_over_axes.__doc__[
480
+ :np.apply_over_axes.__doc__.find('Notes')].rstrip() + \
481
+ """
482
+
483
+ Examples
484
+ --------
485
+ >>> a = np.ma.arange(24).reshape(2,3,4)
486
+ >>> a[:,0,1] = np.ma.masked
487
+ >>> a[:,1,:] = np.ma.masked
488
+ >>> a
489
+ masked_array(
490
+ data=[[[0, --, 2, 3],
491
+ [--, --, --, --],
492
+ [8, 9, 10, 11]],
493
+ [[12, --, 14, 15],
494
+ [--, --, --, --],
495
+ [20, 21, 22, 23]]],
496
+ mask=[[[False, True, False, False],
497
+ [ True, True, True, True],
498
+ [False, False, False, False]],
499
+ [[False, True, False, False],
500
+ [ True, True, True, True],
501
+ [False, False, False, False]]],
502
+ fill_value=999999)
503
+ >>> np.ma.apply_over_axes(np.ma.sum, a, [0,2])
504
+ masked_array(
505
+ data=[[[46],
506
+ [--],
507
+ [124]]],
508
+ mask=[[[False],
509
+ [ True],
510
+ [False]]],
511
+ fill_value=999999)
512
+
513
+ Tuple axis arguments to ufuncs are equivalent:
514
+
515
+ >>> np.ma.sum(a, axis=(0,2)).reshape((1,-1,1))
516
+ masked_array(
517
+ data=[[[46],
518
+ [--],
519
+ [124]]],
520
+ mask=[[[False],
521
+ [ True],
522
+ [False]]],
523
+ fill_value=999999)
524
+ """
525
+
526
+
527
+ def average(a, axis=None, weights=None, returned=False, *,
528
+ keepdims=np._NoValue):
529
+ """
530
+ Return the weighted average of array over the given axis.
531
+
532
+ Parameters
533
+ ----------
534
+ a : array_like
535
+ Data to be averaged.
536
+ Masked entries are not taken into account in the computation.
537
+ axis : int, optional
538
+ Axis along which to average `a`. If None, averaging is done over
539
+ the flattened array.
540
+ weights : array_like, optional
541
+ The importance that each element has in the computation of the average.
542
+ The weights array can either be 1-D (in which case its length must be
543
+ the size of `a` along the given axis) or of the same shape as `a`.
544
+ If ``weights=None``, then all data in `a` are assumed to have a
545
+ weight equal to one. The 1-D calculation is::
546
+
547
+ avg = sum(a * weights) / sum(weights)
548
+
549
+ The only constraint on `weights` is that `sum(weights)` must not be 0.
550
+ returned : bool, optional
551
+ Flag indicating whether a tuple ``(result, sum of weights)``
552
+ should be returned as output (True), or just the result (False).
553
+ Default is False.
554
+ keepdims : bool, optional
555
+ If this is set to True, the axes which are reduced are left
556
+ in the result as dimensions with size one. With this option,
557
+ the result will broadcast correctly against the original `a`.
558
+ *Note:* `keepdims` will not work with instances of `numpy.matrix`
559
+ or other classes whose methods do not support `keepdims`.
560
+
561
+ .. versionadded:: 1.23.0
562
+
563
+ Returns
564
+ -------
565
+ average, [sum_of_weights] : (tuple of) scalar or MaskedArray
566
+ The average along the specified axis. When returned is `True`,
567
+ return a tuple with the average as the first element and the sum
568
+ of the weights as the second element. The return type is `np.float64`
569
+ if `a` is of integer type and floats smaller than `float64`, or the
570
+ input data-type, otherwise. If returned, `sum_of_weights` is always
571
+ `float64`.
572
+
573
+ Examples
574
+ --------
575
+ >>> a = np.ma.array([1., 2., 3., 4.], mask=[False, False, True, True])
576
+ >>> np.ma.average(a, weights=[3, 1, 0, 0])
577
+ 1.25
578
+
579
+ >>> x = np.ma.arange(6.).reshape(3, 2)
580
+ >>> x
581
+ masked_array(
582
+ data=[[0., 1.],
583
+ [2., 3.],
584
+ [4., 5.]],
585
+ mask=False,
586
+ fill_value=1e+20)
587
+ >>> avg, sumweights = np.ma.average(x, axis=0, weights=[1, 2, 3],
588
+ ... returned=True)
589
+ >>> avg
590
+ masked_array(data=[2.6666666666666665, 3.6666666666666665],
591
+ mask=[False, False],
592
+ fill_value=1e+20)
593
+
594
+ With ``keepdims=True``, the following result has shape (3, 1).
595
+
596
+ >>> np.ma.average(x, axis=1, keepdims=True)
597
+ masked_array(
598
+ data=[[0.5],
599
+ [2.5],
600
+ [4.5]],
601
+ mask=False,
602
+ fill_value=1e+20)
603
+ """
604
+ a = asarray(a)
605
+ m = getmask(a)
606
+
607
+ # inspired by 'average' in numpy/lib/function_base.py
608
+
609
+ if keepdims is np._NoValue:
610
+ # Don't pass on the keepdims argument if one wasn't given.
611
+ keepdims_kw = {}
612
+ else:
613
+ keepdims_kw = {'keepdims': keepdims}
614
+
615
+ if weights is None:
616
+ avg = a.mean(axis, **keepdims_kw)
617
+ scl = avg.dtype.type(a.count(axis))
618
+ else:
619
+ wgt = asarray(weights)
620
+
621
+ if issubclass(a.dtype.type, (np.integer, np.bool_)):
622
+ result_dtype = np.result_type(a.dtype, wgt.dtype, 'f8')
623
+ else:
624
+ result_dtype = np.result_type(a.dtype, wgt.dtype)
625
+
626
+ # Sanity checks
627
+ if a.shape != wgt.shape:
628
+ if axis is None:
629
+ raise TypeError(
630
+ "Axis must be specified when shapes of a and weights "
631
+ "differ.")
632
+ if wgt.ndim != 1:
633
+ raise TypeError(
634
+ "1D weights expected when shapes of a and weights differ.")
635
+ if wgt.shape[0] != a.shape[axis]:
636
+ raise ValueError(
637
+ "Length of weights not compatible with specified axis.")
638
+
639
+ # setup wgt to broadcast along axis
640
+ wgt = np.broadcast_to(wgt, (a.ndim-1)*(1,) + wgt.shape, subok=True)
641
+ wgt = wgt.swapaxes(-1, axis)
642
+
643
+ if m is not nomask:
644
+ wgt = wgt*(~a.mask)
645
+ wgt.mask |= a.mask
646
+
647
+ scl = wgt.sum(axis=axis, dtype=result_dtype, **keepdims_kw)
648
+ avg = np.multiply(a, wgt,
649
+ dtype=result_dtype).sum(axis, **keepdims_kw) / scl
650
+
651
+ if returned:
652
+ if scl.shape != avg.shape:
653
+ scl = np.broadcast_to(scl, avg.shape).copy()
654
+ return avg, scl
655
+ else:
656
+ return avg
657
+
658
+
659
+ def median(a, axis=None, out=None, overwrite_input=False, keepdims=False):
660
+ """
661
+ Compute the median along the specified axis.
662
+
663
+ Returns the median of the array elements.
664
+
665
+ Parameters
666
+ ----------
667
+ a : array_like
668
+ Input array or object that can be converted to an array.
669
+ axis : int, optional
670
+ Axis along which the medians are computed. The default (None) is
671
+ to compute the median along a flattened version of the array.
672
+ out : ndarray, optional
673
+ Alternative output array in which to place the result. It must
674
+ have the same shape and buffer length as the expected output
675
+ but the type will be cast if necessary.
676
+ overwrite_input : bool, optional
677
+ If True, then allow use of memory of input array (a) for
678
+ calculations. The input array will be modified by the call to
679
+ median. This will save memory when you do not need to preserve
680
+ the contents of the input array. Treat the input as undefined,
681
+ but it will probably be fully or partially sorted. Default is
682
+ False. Note that, if `overwrite_input` is True, and the input
683
+ is not already an `ndarray`, an error will be raised.
684
+ keepdims : bool, optional
685
+ If this is set to True, the axes which are reduced are left
686
+ in the result as dimensions with size one. With this option,
687
+ the result will broadcast correctly against the input array.
688
+
689
+ .. versionadded:: 1.10.0
690
+
691
+ Returns
692
+ -------
693
+ median : ndarray
694
+ A new array holding the result is returned unless out is
695
+ specified, in which case a reference to out is returned.
696
+ Return data-type is `float64` for integers and floats smaller than
697
+ `float64`, or the input data-type, otherwise.
698
+
699
+ See Also
700
+ --------
701
+ mean
702
+
703
+ Notes
704
+ -----
705
+ Given a vector ``V`` with ``N`` non masked values, the median of ``V``
706
+ is the middle value of a sorted copy of ``V`` (``Vs``) - i.e.
707
+ ``Vs[(N-1)/2]``, when ``N`` is odd, or ``{Vs[N/2 - 1] + Vs[N/2]}/2``
708
+ when ``N`` is even.
709
+
710
+ Examples
711
+ --------
712
+ >>> x = np.ma.array(np.arange(8), mask=[0]*4 + [1]*4)
713
+ >>> np.ma.median(x)
714
+ 1.5
715
+
716
+ >>> x = np.ma.array(np.arange(10).reshape(2, 5), mask=[0]*6 + [1]*4)
717
+ >>> np.ma.median(x)
718
+ 2.5
719
+ >>> np.ma.median(x, axis=-1, overwrite_input=True)
720
+ masked_array(data=[2.0, 5.0],
721
+ mask=[False, False],
722
+ fill_value=1e+20)
723
+
724
+ """
725
+ if not hasattr(a, 'mask'):
726
+ m = np.median(getdata(a, subok=True), axis=axis,
727
+ out=out, overwrite_input=overwrite_input,
728
+ keepdims=keepdims)
729
+ if isinstance(m, np.ndarray) and 1 <= m.ndim:
730
+ return masked_array(m, copy=False)
731
+ else:
732
+ return m
733
+
734
+ return _ureduce(a, func=_median, keepdims=keepdims, axis=axis, out=out,
735
+ overwrite_input=overwrite_input)
736
+
737
+
738
+ def _median(a, axis=None, out=None, overwrite_input=False):
739
+ # when an unmasked NaN is present return it, so we need to sort the NaN
740
+ # values behind the mask
741
+ if np.issubdtype(a.dtype, np.inexact):
742
+ fill_value = np.inf
743
+ else:
744
+ fill_value = None
745
+ if overwrite_input:
746
+ if axis is None:
747
+ asorted = a.ravel()
748
+ asorted.sort(fill_value=fill_value)
749
+ else:
750
+ a.sort(axis=axis, fill_value=fill_value)
751
+ asorted = a
752
+ else:
753
+ asorted = sort(a, axis=axis, fill_value=fill_value)
754
+
755
+ if axis is None:
756
+ axis = 0
757
+ else:
758
+ axis = normalize_axis_index(axis, asorted.ndim)
759
+
760
+ if asorted.shape[axis] == 0:
761
+ # for empty axis integer indices fail so use slicing to get same result
762
+ # as median (which is mean of empty slice = nan)
763
+ indexer = [slice(None)] * asorted.ndim
764
+ indexer[axis] = slice(0, 0)
765
+ indexer = tuple(indexer)
766
+ return np.ma.mean(asorted[indexer], axis=axis, out=out)
767
+
768
+ if asorted.ndim == 1:
769
+ idx, odd = divmod(count(asorted), 2)
770
+ mid = asorted[idx + odd - 1:idx + 1]
771
+ if np.issubdtype(asorted.dtype, np.inexact) and asorted.size > 0:
772
+ # avoid inf / x = masked
773
+ s = mid.sum(out=out)
774
+ if not odd:
775
+ s = np.true_divide(s, 2., casting='safe', out=out)
776
+ s = np.lib.utils._median_nancheck(asorted, s, axis)
777
+ else:
778
+ s = mid.mean(out=out)
779
+
780
+ # if result is masked either the input contained enough
781
+ # minimum_fill_value so that it would be the median or all values
782
+ # masked
783
+ if np.ma.is_masked(s) and not np.all(asorted.mask):
784
+ return np.ma.minimum_fill_value(asorted)
785
+ return s
786
+
787
+ counts = count(asorted, axis=axis, keepdims=True)
788
+ h = counts // 2
789
+
790
+ # duplicate high if odd number of elements so mean does nothing
791
+ odd = counts % 2 == 1
792
+ l = np.where(odd, h, h-1)
793
+
794
+ lh = np.concatenate([l,h], axis=axis)
795
+
796
+ # get low and high median
797
+ low_high = np.take_along_axis(asorted, lh, axis=axis)
798
+
799
+ def replace_masked(s):
800
+ # Replace masked entries with minimum_full_value unless it all values
801
+ # are masked. This is required as the sort order of values equal or
802
+ # larger than the fill value is undefined and a valid value placed
803
+ # elsewhere, e.g. [4, --, inf].
804
+ if np.ma.is_masked(s):
805
+ rep = (~np.all(asorted.mask, axis=axis, keepdims=True)) & s.mask
806
+ s.data[rep] = np.ma.minimum_fill_value(asorted)
807
+ s.mask[rep] = False
808
+
809
+ replace_masked(low_high)
810
+
811
+ if np.issubdtype(asorted.dtype, np.inexact):
812
+ # avoid inf / x = masked
813
+ s = np.ma.sum(low_high, axis=axis, out=out)
814
+ np.true_divide(s.data, 2., casting='unsafe', out=s.data)
815
+
816
+ s = np.lib.utils._median_nancheck(asorted, s, axis)
817
+ else:
818
+ s = np.ma.mean(low_high, axis=axis, out=out)
819
+
820
+ return s
821
+
822
+
823
+ def compress_nd(x, axis=None):
824
+ """Suppress slices from multiple dimensions which contain masked values.
825
+
826
+ Parameters
827
+ ----------
828
+ x : array_like, MaskedArray
829
+ The array to operate on. If not a MaskedArray instance (or if no array
830
+ elements are masked), `x` is interpreted as a MaskedArray with `mask`
831
+ set to `nomask`.
832
+ axis : tuple of ints or int, optional
833
+ Which dimensions to suppress slices from can be configured with this
834
+ parameter.
835
+ - If axis is a tuple of ints, those are the axes to suppress slices from.
836
+ - If axis is an int, then that is the only axis to suppress slices from.
837
+ - If axis is None, all axis are selected.
838
+
839
+ Returns
840
+ -------
841
+ compress_array : ndarray
842
+ The compressed array.
843
+ """
844
+ x = asarray(x)
845
+ m = getmask(x)
846
+ # Set axis to tuple of ints
847
+ if axis is None:
848
+ axis = tuple(range(x.ndim))
849
+ else:
850
+ axis = normalize_axis_tuple(axis, x.ndim)
851
+
852
+ # Nothing is masked: return x
853
+ if m is nomask or not m.any():
854
+ return x._data
855
+ # All is masked: return empty
856
+ if m.all():
857
+ return nxarray([])
858
+ # Filter elements through boolean indexing
859
+ data = x._data
860
+ for ax in axis:
861
+ axes = tuple(list(range(ax)) + list(range(ax + 1, x.ndim)))
862
+ data = data[(slice(None),)*ax + (~m.any(axis=axes),)]
863
+ return data
864
+
865
+
866
+ def compress_rowcols(x, axis=None):
867
+ """
868
+ Suppress the rows and/or columns of a 2-D array that contain
869
+ masked values.
870
+
871
+ The suppression behavior is selected with the `axis` parameter.
872
+
873
+ - If axis is None, both rows and columns are suppressed.
874
+ - If axis is 0, only rows are suppressed.
875
+ - If axis is 1 or -1, only columns are suppressed.
876
+
877
+ Parameters
878
+ ----------
879
+ x : array_like, MaskedArray
880
+ The array to operate on. If not a MaskedArray instance (or if no array
881
+ elements are masked), `x` is interpreted as a MaskedArray with
882
+ `mask` set to `nomask`. Must be a 2D array.
883
+ axis : int, optional
884
+ Axis along which to perform the operation. Default is None.
885
+
886
+ Returns
887
+ -------
888
+ compressed_array : ndarray
889
+ The compressed array.
890
+
891
+ Examples
892
+ --------
893
+ >>> x = np.ma.array(np.arange(9).reshape(3, 3), mask=[[1, 0, 0],
894
+ ... [1, 0, 0],
895
+ ... [0, 0, 0]])
896
+ >>> x
897
+ masked_array(
898
+ data=[[--, 1, 2],
899
+ [--, 4, 5],
900
+ [6, 7, 8]],
901
+ mask=[[ True, False, False],
902
+ [ True, False, False],
903
+ [False, False, False]],
904
+ fill_value=999999)
905
+
906
+ >>> np.ma.compress_rowcols(x)
907
+ array([[7, 8]])
908
+ >>> np.ma.compress_rowcols(x, 0)
909
+ array([[6, 7, 8]])
910
+ >>> np.ma.compress_rowcols(x, 1)
911
+ array([[1, 2],
912
+ [4, 5],
913
+ [7, 8]])
914
+
915
+ """
916
+ if asarray(x).ndim != 2:
917
+ raise NotImplementedError("compress_rowcols works for 2D arrays only.")
918
+ return compress_nd(x, axis=axis)
919
+
920
+
921
+ def compress_rows(a):
922
+ """
923
+ Suppress whole rows of a 2-D array that contain masked values.
924
+
925
+ This is equivalent to ``np.ma.compress_rowcols(a, 0)``, see
926
+ `compress_rowcols` for details.
927
+
928
+ See Also
929
+ --------
930
+ compress_rowcols
931
+
932
+ """
933
+ a = asarray(a)
934
+ if a.ndim != 2:
935
+ raise NotImplementedError("compress_rows works for 2D arrays only.")
936
+ return compress_rowcols(a, 0)
937
+
938
+
939
+ def compress_cols(a):
940
+ """
941
+ Suppress whole columns of a 2-D array that contain masked values.
942
+
943
+ This is equivalent to ``np.ma.compress_rowcols(a, 1)``, see
944
+ `compress_rowcols` for details.
945
+
946
+ See Also
947
+ --------
948
+ compress_rowcols
949
+
950
+ """
951
+ a = asarray(a)
952
+ if a.ndim != 2:
953
+ raise NotImplementedError("compress_cols works for 2D arrays only.")
954
+ return compress_rowcols(a, 1)
955
+
956
+
957
+ def mask_rowcols(a, axis=None):
958
+ """
959
+ Mask rows and/or columns of a 2D array that contain masked values.
960
+
961
+ Mask whole rows and/or columns of a 2D array that contain
962
+ masked values. The masking behavior is selected using the
963
+ `axis` parameter.
964
+
965
+ - If `axis` is None, rows *and* columns are masked.
966
+ - If `axis` is 0, only rows are masked.
967
+ - If `axis` is 1 or -1, only columns are masked.
968
+
969
+ Parameters
970
+ ----------
971
+ a : array_like, MaskedArray
972
+ The array to mask. If not a MaskedArray instance (or if no array
973
+ elements are masked), the result is a MaskedArray with `mask` set
974
+ to `nomask` (False). Must be a 2D array.
975
+ axis : int, optional
976
+ Axis along which to perform the operation. If None, applies to a
977
+ flattened version of the array.
978
+
979
+ Returns
980
+ -------
981
+ a : MaskedArray
982
+ A modified version of the input array, masked depending on the value
983
+ of the `axis` parameter.
984
+
985
+ Raises
986
+ ------
987
+ NotImplementedError
988
+ If input array `a` is not 2D.
989
+
990
+ See Also
991
+ --------
992
+ mask_rows : Mask rows of a 2D array that contain masked values.
993
+ mask_cols : Mask cols of a 2D array that contain masked values.
994
+ masked_where : Mask where a condition is met.
995
+
996
+ Notes
997
+ -----
998
+ The input array's mask is modified by this function.
999
+
1000
+ Examples
1001
+ --------
1002
+ >>> import numpy.ma as ma
1003
+ >>> a = np.zeros((3, 3), dtype=int)
1004
+ >>> a[1, 1] = 1
1005
+ >>> a
1006
+ array([[0, 0, 0],
1007
+ [0, 1, 0],
1008
+ [0, 0, 0]])
1009
+ >>> a = ma.masked_equal(a, 1)
1010
+ >>> a
1011
+ masked_array(
1012
+ data=[[0, 0, 0],
1013
+ [0, --, 0],
1014
+ [0, 0, 0]],
1015
+ mask=[[False, False, False],
1016
+ [False, True, False],
1017
+ [False, False, False]],
1018
+ fill_value=1)
1019
+ >>> ma.mask_rowcols(a)
1020
+ masked_array(
1021
+ data=[[0, --, 0],
1022
+ [--, --, --],
1023
+ [0, --, 0]],
1024
+ mask=[[False, True, False],
1025
+ [ True, True, True],
1026
+ [False, True, False]],
1027
+ fill_value=1)
1028
+
1029
+ """
1030
+ a = array(a, subok=False)
1031
+ if a.ndim != 2:
1032
+ raise NotImplementedError("mask_rowcols works for 2D arrays only.")
1033
+ m = getmask(a)
1034
+ # Nothing is masked: return a
1035
+ if m is nomask or not m.any():
1036
+ return a
1037
+ maskedval = m.nonzero()
1038
+ a._mask = a._mask.copy()
1039
+ if not axis:
1040
+ a[np.unique(maskedval[0])] = masked
1041
+ if axis in [None, 1, -1]:
1042
+ a[:, np.unique(maskedval[1])] = masked
1043
+ return a
1044
+
1045
+
1046
+ def mask_rows(a, axis=np._NoValue):
1047
+ """
1048
+ Mask rows of a 2D array that contain masked values.
1049
+
1050
+ This function is a shortcut to ``mask_rowcols`` with `axis` equal to 0.
1051
+
1052
+ See Also
1053
+ --------
1054
+ mask_rowcols : Mask rows and/or columns of a 2D array.
1055
+ masked_where : Mask where a condition is met.
1056
+
1057
+ Examples
1058
+ --------
1059
+ >>> import numpy.ma as ma
1060
+ >>> a = np.zeros((3, 3), dtype=int)
1061
+ >>> a[1, 1] = 1
1062
+ >>> a
1063
+ array([[0, 0, 0],
1064
+ [0, 1, 0],
1065
+ [0, 0, 0]])
1066
+ >>> a = ma.masked_equal(a, 1)
1067
+ >>> a
1068
+ masked_array(
1069
+ data=[[0, 0, 0],
1070
+ [0, --, 0],
1071
+ [0, 0, 0]],
1072
+ mask=[[False, False, False],
1073
+ [False, True, False],
1074
+ [False, False, False]],
1075
+ fill_value=1)
1076
+
1077
+ >>> ma.mask_rows(a)
1078
+ masked_array(
1079
+ data=[[0, 0, 0],
1080
+ [--, --, --],
1081
+ [0, 0, 0]],
1082
+ mask=[[False, False, False],
1083
+ [ True, True, True],
1084
+ [False, False, False]],
1085
+ fill_value=1)
1086
+
1087
+ """
1088
+ if axis is not np._NoValue:
1089
+ # remove the axis argument when this deprecation expires
1090
+ # NumPy 1.18.0, 2019-11-28
1091
+ warnings.warn(
1092
+ "The axis argument has always been ignored, in future passing it "
1093
+ "will raise TypeError", DeprecationWarning, stacklevel=2)
1094
+ return mask_rowcols(a, 0)
1095
+
1096
+
1097
+ def mask_cols(a, axis=np._NoValue):
1098
+ """
1099
+ Mask columns of a 2D array that contain masked values.
1100
+
1101
+ This function is a shortcut to ``mask_rowcols`` with `axis` equal to 1.
1102
+
1103
+ See Also
1104
+ --------
1105
+ mask_rowcols : Mask rows and/or columns of a 2D array.
1106
+ masked_where : Mask where a condition is met.
1107
+
1108
+ Examples
1109
+ --------
1110
+ >>> import numpy.ma as ma
1111
+ >>> a = np.zeros((3, 3), dtype=int)
1112
+ >>> a[1, 1] = 1
1113
+ >>> a
1114
+ array([[0, 0, 0],
1115
+ [0, 1, 0],
1116
+ [0, 0, 0]])
1117
+ >>> a = ma.masked_equal(a, 1)
1118
+ >>> a
1119
+ masked_array(
1120
+ data=[[0, 0, 0],
1121
+ [0, --, 0],
1122
+ [0, 0, 0]],
1123
+ mask=[[False, False, False],
1124
+ [False, True, False],
1125
+ [False, False, False]],
1126
+ fill_value=1)
1127
+ >>> ma.mask_cols(a)
1128
+ masked_array(
1129
+ data=[[0, --, 0],
1130
+ [0, --, 0],
1131
+ [0, --, 0]],
1132
+ mask=[[False, True, False],
1133
+ [False, True, False],
1134
+ [False, True, False]],
1135
+ fill_value=1)
1136
+
1137
+ """
1138
+ if axis is not np._NoValue:
1139
+ # remove the axis argument when this deprecation expires
1140
+ # NumPy 1.18.0, 2019-11-28
1141
+ warnings.warn(
1142
+ "The axis argument has always been ignored, in future passing it "
1143
+ "will raise TypeError", DeprecationWarning, stacklevel=2)
1144
+ return mask_rowcols(a, 1)
1145
+
1146
+
1147
+ #####--------------------------------------------------------------------------
1148
+ #---- --- arraysetops ---
1149
+ #####--------------------------------------------------------------------------
1150
+
1151
+ def ediff1d(arr, to_end=None, to_begin=None):
1152
+ """
1153
+ Compute the differences between consecutive elements of an array.
1154
+
1155
+ This function is the equivalent of `numpy.ediff1d` that takes masked
1156
+ values into account, see `numpy.ediff1d` for details.
1157
+
1158
+ See Also
1159
+ --------
1160
+ numpy.ediff1d : Equivalent function for ndarrays.
1161
+
1162
+ """
1163
+ arr = ma.asanyarray(arr).flat
1164
+ ed = arr[1:] - arr[:-1]
1165
+ arrays = [ed]
1166
+ #
1167
+ if to_begin is not None:
1168
+ arrays.insert(0, to_begin)
1169
+ if to_end is not None:
1170
+ arrays.append(to_end)
1171
+ #
1172
+ if len(arrays) != 1:
1173
+ # We'll save ourselves a copy of a potentially large array in the common
1174
+ # case where neither to_begin or to_end was given.
1175
+ ed = hstack(arrays)
1176
+ #
1177
+ return ed
1178
+
1179
+
1180
+ def unique(ar1, return_index=False, return_inverse=False):
1181
+ """
1182
+ Finds the unique elements of an array.
1183
+
1184
+ Masked values are considered the same element (masked). The output array
1185
+ is always a masked array. See `numpy.unique` for more details.
1186
+
1187
+ See Also
1188
+ --------
1189
+ numpy.unique : Equivalent function for ndarrays.
1190
+
1191
+ Examples
1192
+ --------
1193
+ >>> import numpy.ma as ma
1194
+ >>> a = [1, 2, 1000, 2, 3]
1195
+ >>> mask = [0, 0, 1, 0, 0]
1196
+ >>> masked_a = ma.masked_array(a, mask)
1197
+ >>> masked_a
1198
+ masked_array(data=[1, 2, --, 2, 3],
1199
+ mask=[False, False, True, False, False],
1200
+ fill_value=999999)
1201
+ >>> ma.unique(masked_a)
1202
+ masked_array(data=[1, 2, 3, --],
1203
+ mask=[False, False, False, True],
1204
+ fill_value=999999)
1205
+ >>> ma.unique(masked_a, return_index=True)
1206
+ (masked_array(data=[1, 2, 3, --],
1207
+ mask=[False, False, False, True],
1208
+ fill_value=999999), array([0, 1, 4, 2]))
1209
+ >>> ma.unique(masked_a, return_inverse=True)
1210
+ (masked_array(data=[1, 2, 3, --],
1211
+ mask=[False, False, False, True],
1212
+ fill_value=999999), array([0, 1, 3, 1, 2]))
1213
+ >>> ma.unique(masked_a, return_index=True, return_inverse=True)
1214
+ (masked_array(data=[1, 2, 3, --],
1215
+ mask=[False, False, False, True],
1216
+ fill_value=999999), array([0, 1, 4, 2]), array([0, 1, 3, 1, 2]))
1217
+ """
1218
+ output = np.unique(ar1,
1219
+ return_index=return_index,
1220
+ return_inverse=return_inverse)
1221
+ if isinstance(output, tuple):
1222
+ output = list(output)
1223
+ output[0] = output[0].view(MaskedArray)
1224
+ output = tuple(output)
1225
+ else:
1226
+ output = output.view(MaskedArray)
1227
+ return output
1228
+
1229
+
1230
+ def intersect1d(ar1, ar2, assume_unique=False):
1231
+ """
1232
+ Returns the unique elements common to both arrays.
1233
+
1234
+ Masked values are considered equal one to the other.
1235
+ The output is always a masked array.
1236
+
1237
+ See `numpy.intersect1d` for more details.
1238
+
1239
+ See Also
1240
+ --------
1241
+ numpy.intersect1d : Equivalent function for ndarrays.
1242
+
1243
+ Examples
1244
+ --------
1245
+ >>> x = np.ma.array([1, 3, 3, 3], mask=[0, 0, 0, 1])
1246
+ >>> y = np.ma.array([3, 1, 1, 1], mask=[0, 0, 0, 1])
1247
+ >>> np.ma.intersect1d(x, y)
1248
+ masked_array(data=[1, 3, --],
1249
+ mask=[False, False, True],
1250
+ fill_value=999999)
1251
+
1252
+ """
1253
+ if assume_unique:
1254
+ aux = ma.concatenate((ar1, ar2))
1255
+ else:
1256
+ # Might be faster than unique( intersect1d( ar1, ar2 ) )?
1257
+ aux = ma.concatenate((unique(ar1), unique(ar2)))
1258
+ aux.sort()
1259
+ return aux[:-1][aux[1:] == aux[:-1]]
1260
+
1261
+
1262
+ def setxor1d(ar1, ar2, assume_unique=False):
1263
+ """
1264
+ Set exclusive-or of 1-D arrays with unique elements.
1265
+
1266
+ The output is always a masked array. See `numpy.setxor1d` for more details.
1267
+
1268
+ See Also
1269
+ --------
1270
+ numpy.setxor1d : Equivalent function for ndarrays.
1271
+
1272
+ """
1273
+ if not assume_unique:
1274
+ ar1 = unique(ar1)
1275
+ ar2 = unique(ar2)
1276
+
1277
+ aux = ma.concatenate((ar1, ar2))
1278
+ if aux.size == 0:
1279
+ return aux
1280
+ aux.sort()
1281
+ auxf = aux.filled()
1282
+ # flag = ediff1d( aux, to_end = 1, to_begin = 1 ) == 0
1283
+ flag = ma.concatenate(([True], (auxf[1:] != auxf[:-1]), [True]))
1284
+ # flag2 = ediff1d( flag ) == 0
1285
+ flag2 = (flag[1:] == flag[:-1])
1286
+ return aux[flag2]
1287
+
1288
+
1289
+ def in1d(ar1, ar2, assume_unique=False, invert=False):
1290
+ """
1291
+ Test whether each element of an array is also present in a second
1292
+ array.
1293
+
1294
+ The output is always a masked array. See `numpy.in1d` for more details.
1295
+
1296
+ We recommend using :func:`isin` instead of `in1d` for new code.
1297
+
1298
+ See Also
1299
+ --------
1300
+ isin : Version of this function that preserves the shape of ar1.
1301
+ numpy.in1d : Equivalent function for ndarrays.
1302
+
1303
+ Notes
1304
+ -----
1305
+ .. versionadded:: 1.4.0
1306
+
1307
+ """
1308
+ if not assume_unique:
1309
+ ar1, rev_idx = unique(ar1, return_inverse=True)
1310
+ ar2 = unique(ar2)
1311
+
1312
+ ar = ma.concatenate((ar1, ar2))
1313
+ # We need this to be a stable sort, so always use 'mergesort'
1314
+ # here. The values from the first array should always come before
1315
+ # the values from the second array.
1316
+ order = ar.argsort(kind='mergesort')
1317
+ sar = ar[order]
1318
+ if invert:
1319
+ bool_ar = (sar[1:] != sar[:-1])
1320
+ else:
1321
+ bool_ar = (sar[1:] == sar[:-1])
1322
+ flag = ma.concatenate((bool_ar, [invert]))
1323
+ indx = order.argsort(kind='mergesort')[:len(ar1)]
1324
+
1325
+ if assume_unique:
1326
+ return flag[indx]
1327
+ else:
1328
+ return flag[indx][rev_idx]
1329
+
1330
+
1331
+ def isin(element, test_elements, assume_unique=False, invert=False):
1332
+ """
1333
+ Calculates `element in test_elements`, broadcasting over
1334
+ `element` only.
1335
+
1336
+ The output is always a masked array of the same shape as `element`.
1337
+ See `numpy.isin` for more details.
1338
+
1339
+ See Also
1340
+ --------
1341
+ in1d : Flattened version of this function.
1342
+ numpy.isin : Equivalent function for ndarrays.
1343
+
1344
+ Notes
1345
+ -----
1346
+ .. versionadded:: 1.13.0
1347
+
1348
+ """
1349
+ element = ma.asarray(element)
1350
+ return in1d(element, test_elements, assume_unique=assume_unique,
1351
+ invert=invert).reshape(element.shape)
1352
+
1353
+
1354
+ def union1d(ar1, ar2):
1355
+ """
1356
+ Union of two arrays.
1357
+
1358
+ The output is always a masked array. See `numpy.union1d` for more details.
1359
+
1360
+ See Also
1361
+ --------
1362
+ numpy.union1d : Equivalent function for ndarrays.
1363
+
1364
+ """
1365
+ return unique(ma.concatenate((ar1, ar2), axis=None))
1366
+
1367
+
1368
+ def setdiff1d(ar1, ar2, assume_unique=False):
1369
+ """
1370
+ Set difference of 1D arrays with unique elements.
1371
+
1372
+ The output is always a masked array. See `numpy.setdiff1d` for more
1373
+ details.
1374
+
1375
+ See Also
1376
+ --------
1377
+ numpy.setdiff1d : Equivalent function for ndarrays.
1378
+
1379
+ Examples
1380
+ --------
1381
+ >>> x = np.ma.array([1, 2, 3, 4], mask=[0, 1, 0, 1])
1382
+ >>> np.ma.setdiff1d(x, [1, 2])
1383
+ masked_array(data=[3, --],
1384
+ mask=[False, True],
1385
+ fill_value=999999)
1386
+
1387
+ """
1388
+ if assume_unique:
1389
+ ar1 = ma.asarray(ar1).ravel()
1390
+ else:
1391
+ ar1 = unique(ar1)
1392
+ ar2 = unique(ar2)
1393
+ return ar1[in1d(ar1, ar2, assume_unique=True, invert=True)]
1394
+
1395
+
1396
+ ###############################################################################
1397
+ # Covariance #
1398
+ ###############################################################################
1399
+
1400
+
1401
+ def _covhelper(x, y=None, rowvar=True, allow_masked=True):
1402
+ """
1403
+ Private function for the computation of covariance and correlation
1404
+ coefficients.
1405
+
1406
+ """
1407
+ x = ma.array(x, ndmin=2, copy=True, dtype=float)
1408
+ xmask = ma.getmaskarray(x)
1409
+ # Quick exit if we can't process masked data
1410
+ if not allow_masked and xmask.any():
1411
+ raise ValueError("Cannot process masked data.")
1412
+ #
1413
+ if x.shape[0] == 1:
1414
+ rowvar = True
1415
+ # Make sure that rowvar is either 0 or 1
1416
+ rowvar = int(bool(rowvar))
1417
+ axis = 1 - rowvar
1418
+ if rowvar:
1419
+ tup = (slice(None), None)
1420
+ else:
1421
+ tup = (None, slice(None))
1422
+ #
1423
+ if y is None:
1424
+ xnotmask = np.logical_not(xmask).astype(int)
1425
+ else:
1426
+ y = array(y, copy=False, ndmin=2, dtype=float)
1427
+ ymask = ma.getmaskarray(y)
1428
+ if not allow_masked and ymask.any():
1429
+ raise ValueError("Cannot process masked data.")
1430
+ if xmask.any() or ymask.any():
1431
+ if y.shape == x.shape:
1432
+ # Define some common mask
1433
+ common_mask = np.logical_or(xmask, ymask)
1434
+ if common_mask is not nomask:
1435
+ xmask = x._mask = y._mask = ymask = common_mask
1436
+ x._sharedmask = False
1437
+ y._sharedmask = False
1438
+ x = ma.concatenate((x, y), axis)
1439
+ xnotmask = np.logical_not(np.concatenate((xmask, ymask), axis)).astype(int)
1440
+ x -= x.mean(axis=rowvar)[tup]
1441
+ return (x, xnotmask, rowvar)
1442
+
1443
+
1444
+ def cov(x, y=None, rowvar=True, bias=False, allow_masked=True, ddof=None):
1445
+ """
1446
+ Estimate the covariance matrix.
1447
+
1448
+ Except for the handling of missing data this function does the same as
1449
+ `numpy.cov`. For more details and examples, see `numpy.cov`.
1450
+
1451
+ By default, masked values are recognized as such. If `x` and `y` have the
1452
+ same shape, a common mask is allocated: if ``x[i,j]`` is masked, then
1453
+ ``y[i,j]`` will also be masked.
1454
+ Setting `allow_masked` to False will raise an exception if values are
1455
+ missing in either of the input arrays.
1456
+
1457
+ Parameters
1458
+ ----------
1459
+ x : array_like
1460
+ A 1-D or 2-D array containing multiple variables and observations.
1461
+ Each row of `x` represents a variable, and each column a single
1462
+ observation of all those variables. Also see `rowvar` below.
1463
+ y : array_like, optional
1464
+ An additional set of variables and observations. `y` has the same
1465
+ shape as `x`.
1466
+ rowvar : bool, optional
1467
+ If `rowvar` is True (default), then each row represents a
1468
+ variable, with observations in the columns. Otherwise, the relationship
1469
+ is transposed: each column represents a variable, while the rows
1470
+ contain observations.
1471
+ bias : bool, optional
1472
+ Default normalization (False) is by ``(N-1)``, where ``N`` is the
1473
+ number of observations given (unbiased estimate). If `bias` is True,
1474
+ then normalization is by ``N``. This keyword can be overridden by
1475
+ the keyword ``ddof`` in numpy versions >= 1.5.
1476
+ allow_masked : bool, optional
1477
+ If True, masked values are propagated pair-wise: if a value is masked
1478
+ in `x`, the corresponding value is masked in `y`.
1479
+ If False, raises a `ValueError` exception when some values are missing.
1480
+ ddof : {None, int}, optional
1481
+ If not ``None`` normalization is by ``(N - ddof)``, where ``N`` is
1482
+ the number of observations; this overrides the value implied by
1483
+ ``bias``. The default value is ``None``.
1484
+
1485
+ .. versionadded:: 1.5
1486
+
1487
+ Raises
1488
+ ------
1489
+ ValueError
1490
+ Raised if some values are missing and `allow_masked` is False.
1491
+
1492
+ See Also
1493
+ --------
1494
+ numpy.cov
1495
+
1496
+ """
1497
+ # Check inputs
1498
+ if ddof is not None and ddof != int(ddof):
1499
+ raise ValueError("ddof must be an integer")
1500
+ # Set up ddof
1501
+ if ddof is None:
1502
+ if bias:
1503
+ ddof = 0
1504
+ else:
1505
+ ddof = 1
1506
+
1507
+ (x, xnotmask, rowvar) = _covhelper(x, y, rowvar, allow_masked)
1508
+ if not rowvar:
1509
+ fact = np.dot(xnotmask.T, xnotmask) * 1. - ddof
1510
+ result = (dot(x.T, x.conj(), strict=False) / fact).squeeze()
1511
+ else:
1512
+ fact = np.dot(xnotmask, xnotmask.T) * 1. - ddof
1513
+ result = (dot(x, x.T.conj(), strict=False) / fact).squeeze()
1514
+ return result
1515
+
1516
+
1517
+ def corrcoef(x, y=None, rowvar=True, bias=np._NoValue, allow_masked=True,
1518
+ ddof=np._NoValue):
1519
+ """
1520
+ Return Pearson product-moment correlation coefficients.
1521
+
1522
+ Except for the handling of missing data this function does the same as
1523
+ `numpy.corrcoef`. For more details and examples, see `numpy.corrcoef`.
1524
+
1525
+ Parameters
1526
+ ----------
1527
+ x : array_like
1528
+ A 1-D or 2-D array containing multiple variables and observations.
1529
+ Each row of `x` represents a variable, and each column a single
1530
+ observation of all those variables. Also see `rowvar` below.
1531
+ y : array_like, optional
1532
+ An additional set of variables and observations. `y` has the same
1533
+ shape as `x`.
1534
+ rowvar : bool, optional
1535
+ If `rowvar` is True (default), then each row represents a
1536
+ variable, with observations in the columns. Otherwise, the relationship
1537
+ is transposed: each column represents a variable, while the rows
1538
+ contain observations.
1539
+ bias : _NoValue, optional
1540
+ Has no effect, do not use.
1541
+
1542
+ .. deprecated:: 1.10.0
1543
+ allow_masked : bool, optional
1544
+ If True, masked values are propagated pair-wise: if a value is masked
1545
+ in `x`, the corresponding value is masked in `y`.
1546
+ If False, raises an exception. Because `bias` is deprecated, this
1547
+ argument needs to be treated as keyword only to avoid a warning.
1548
+ ddof : _NoValue, optional
1549
+ Has no effect, do not use.
1550
+
1551
+ .. deprecated:: 1.10.0
1552
+
1553
+ See Also
1554
+ --------
1555
+ numpy.corrcoef : Equivalent function in top-level NumPy module.
1556
+ cov : Estimate the covariance matrix.
1557
+
1558
+ Notes
1559
+ -----
1560
+ This function accepts but discards arguments `bias` and `ddof`. This is
1561
+ for backwards compatibility with previous versions of this function. These
1562
+ arguments had no effect on the return values of the function and can be
1563
+ safely ignored in this and previous versions of numpy.
1564
+ """
1565
+ msg = 'bias and ddof have no effect and are deprecated'
1566
+ if bias is not np._NoValue or ddof is not np._NoValue:
1567
+ # 2015-03-15, 1.10
1568
+ warnings.warn(msg, DeprecationWarning, stacklevel=2)
1569
+ # Get the data
1570
+ (x, xnotmask, rowvar) = _covhelper(x, y, rowvar, allow_masked)
1571
+ # Compute the covariance matrix
1572
+ if not rowvar:
1573
+ fact = np.dot(xnotmask.T, xnotmask) * 1.
1574
+ c = (dot(x.T, x.conj(), strict=False) / fact).squeeze()
1575
+ else:
1576
+ fact = np.dot(xnotmask, xnotmask.T) * 1.
1577
+ c = (dot(x, x.T.conj(), strict=False) / fact).squeeze()
1578
+ # Check whether we have a scalar
1579
+ try:
1580
+ diag = ma.diagonal(c)
1581
+ except ValueError:
1582
+ return 1
1583
+ #
1584
+ if xnotmask.all():
1585
+ _denom = ma.sqrt(ma.multiply.outer(diag, diag))
1586
+ else:
1587
+ _denom = diagflat(diag)
1588
+ _denom._sharedmask = False # We know return is always a copy
1589
+ n = x.shape[1 - rowvar]
1590
+ if rowvar:
1591
+ for i in range(n - 1):
1592
+ for j in range(i + 1, n):
1593
+ _x = mask_cols(vstack((x[i], x[j]))).var(axis=1)
1594
+ _denom[i, j] = _denom[j, i] = ma.sqrt(ma.multiply.reduce(_x))
1595
+ else:
1596
+ for i in range(n - 1):
1597
+ for j in range(i + 1, n):
1598
+ _x = mask_cols(
1599
+ vstack((x[:, i], x[:, j]))).var(axis=1)
1600
+ _denom[i, j] = _denom[j, i] = ma.sqrt(ma.multiply.reduce(_x))
1601
+ return c / _denom
1602
+
1603
+ #####--------------------------------------------------------------------------
1604
+ #---- --- Concatenation helpers ---
1605
+ #####--------------------------------------------------------------------------
1606
+
1607
+ class MAxisConcatenator(AxisConcatenator):
1608
+ """
1609
+ Translate slice objects to concatenation along an axis.
1610
+
1611
+ For documentation on usage, see `mr_class`.
1612
+
1613
+ See Also
1614
+ --------
1615
+ mr_class
1616
+
1617
+ """
1618
+ concatenate = staticmethod(concatenate)
1619
+
1620
+ @classmethod
1621
+ def makemat(cls, arr):
1622
+ # There used to be a view as np.matrix here, but we may eventually
1623
+ # deprecate that class. In preparation, we use the unmasked version
1624
+ # to construct the matrix (with copy=False for backwards compatibility
1625
+ # with the .view)
1626
+ data = super().makemat(arr.data, copy=False)
1627
+ return array(data, mask=arr.mask)
1628
+
1629
+ def __getitem__(self, key):
1630
+ # matrix builder syntax, like 'a, b; c, d'
1631
+ if isinstance(key, str):
1632
+ raise MAError("Unavailable for masked array.")
1633
+
1634
+ return super().__getitem__(key)
1635
+
1636
+
1637
+ class mr_class(MAxisConcatenator):
1638
+ """
1639
+ Translate slice objects to concatenation along the first axis.
1640
+
1641
+ This is the masked array version of `lib.index_tricks.RClass`.
1642
+
1643
+ See Also
1644
+ --------
1645
+ lib.index_tricks.RClass
1646
+
1647
+ Examples
1648
+ --------
1649
+ >>> np.ma.mr_[np.ma.array([1,2,3]), 0, 0, np.ma.array([4,5,6])]
1650
+ masked_array(data=[1, 2, 3, ..., 4, 5, 6],
1651
+ mask=False,
1652
+ fill_value=999999)
1653
+
1654
+ """
1655
+ def __init__(self):
1656
+ MAxisConcatenator.__init__(self, 0)
1657
+
1658
+ mr_ = mr_class()
1659
+
1660
+
1661
+ #####--------------------------------------------------------------------------
1662
+ #---- Find unmasked data ---
1663
+ #####--------------------------------------------------------------------------
1664
+
1665
+ def ndenumerate(a, compressed=True):
1666
+ """
1667
+ Multidimensional index iterator.
1668
+
1669
+ Return an iterator yielding pairs of array coordinates and values,
1670
+ skipping elements that are masked. With `compressed=False`,
1671
+ `ma.masked` is yielded as the value of masked elements. This
1672
+ behavior differs from that of `numpy.ndenumerate`, which yields the
1673
+ value of the underlying data array.
1674
+
1675
+ Notes
1676
+ -----
1677
+ .. versionadded:: 1.23.0
1678
+
1679
+ Parameters
1680
+ ----------
1681
+ a : array_like
1682
+ An array with (possibly) masked elements.
1683
+ compressed : bool, optional
1684
+ If True (default), masked elements are skipped.
1685
+
1686
+ See Also
1687
+ --------
1688
+ numpy.ndenumerate : Equivalent function ignoring any mask.
1689
+
1690
+ Examples
1691
+ --------
1692
+ >>> a = np.ma.arange(9).reshape((3, 3))
1693
+ >>> a[1, 0] = np.ma.masked
1694
+ >>> a[1, 2] = np.ma.masked
1695
+ >>> a[2, 1] = np.ma.masked
1696
+ >>> a
1697
+ masked_array(
1698
+ data=[[0, 1, 2],
1699
+ [--, 4, --],
1700
+ [6, --, 8]],
1701
+ mask=[[False, False, False],
1702
+ [ True, False, True],
1703
+ [False, True, False]],
1704
+ fill_value=999999)
1705
+ >>> for index, x in np.ma.ndenumerate(a):
1706
+ ... print(index, x)
1707
+ (0, 0) 0
1708
+ (0, 1) 1
1709
+ (0, 2) 2
1710
+ (1, 1) 4
1711
+ (2, 0) 6
1712
+ (2, 2) 8
1713
+
1714
+ >>> for index, x in np.ma.ndenumerate(a, compressed=False):
1715
+ ... print(index, x)
1716
+ (0, 0) 0
1717
+ (0, 1) 1
1718
+ (0, 2) 2
1719
+ (1, 0) --
1720
+ (1, 1) 4
1721
+ (1, 2) --
1722
+ (2, 0) 6
1723
+ (2, 1) --
1724
+ (2, 2) 8
1725
+ """
1726
+ for it, mask in zip(np.ndenumerate(a), getmaskarray(a).flat):
1727
+ if not mask:
1728
+ yield it
1729
+ elif not compressed:
1730
+ yield it[0], masked
1731
+
1732
+
1733
+ def flatnotmasked_edges(a):
1734
+ """
1735
+ Find the indices of the first and last unmasked values.
1736
+
1737
+ Expects a 1-D `MaskedArray`, returns None if all values are masked.
1738
+
1739
+ Parameters
1740
+ ----------
1741
+ a : array_like
1742
+ Input 1-D `MaskedArray`
1743
+
1744
+ Returns
1745
+ -------
1746
+ edges : ndarray or None
1747
+ The indices of first and last non-masked value in the array.
1748
+ Returns None if all values are masked.
1749
+
1750
+ See Also
1751
+ --------
1752
+ flatnotmasked_contiguous, notmasked_contiguous, notmasked_edges
1753
+ clump_masked, clump_unmasked
1754
+
1755
+ Notes
1756
+ -----
1757
+ Only accepts 1-D arrays.
1758
+
1759
+ Examples
1760
+ --------
1761
+ >>> a = np.ma.arange(10)
1762
+ >>> np.ma.flatnotmasked_edges(a)
1763
+ array([0, 9])
1764
+
1765
+ >>> mask = (a < 3) | (a > 8) | (a == 5)
1766
+ >>> a[mask] = np.ma.masked
1767
+ >>> np.array(a[~a.mask])
1768
+ array([3, 4, 6, 7, 8])
1769
+
1770
+ >>> np.ma.flatnotmasked_edges(a)
1771
+ array([3, 8])
1772
+
1773
+ >>> a[:] = np.ma.masked
1774
+ >>> print(np.ma.flatnotmasked_edges(a))
1775
+ None
1776
+
1777
+ """
1778
+ m = getmask(a)
1779
+ if m is nomask or not np.any(m):
1780
+ return np.array([0, a.size - 1])
1781
+ unmasked = np.flatnonzero(~m)
1782
+ if len(unmasked) > 0:
1783
+ return unmasked[[0, -1]]
1784
+ else:
1785
+ return None
1786
+
1787
+
1788
+ def notmasked_edges(a, axis=None):
1789
+ """
1790
+ Find the indices of the first and last unmasked values along an axis.
1791
+
1792
+ If all values are masked, return None. Otherwise, return a list
1793
+ of two tuples, corresponding to the indices of the first and last
1794
+ unmasked values respectively.
1795
+
1796
+ Parameters
1797
+ ----------
1798
+ a : array_like
1799
+ The input array.
1800
+ axis : int, optional
1801
+ Axis along which to perform the operation.
1802
+ If None (default), applies to a flattened version of the array.
1803
+
1804
+ Returns
1805
+ -------
1806
+ edges : ndarray or list
1807
+ An array of start and end indexes if there are any masked data in
1808
+ the array. If there are no masked data in the array, `edges` is a
1809
+ list of the first and last index.
1810
+
1811
+ See Also
1812
+ --------
1813
+ flatnotmasked_contiguous, flatnotmasked_edges, notmasked_contiguous
1814
+ clump_masked, clump_unmasked
1815
+
1816
+ Examples
1817
+ --------
1818
+ >>> a = np.arange(9).reshape((3, 3))
1819
+ >>> m = np.zeros_like(a)
1820
+ >>> m[1:, 1:] = 1
1821
+
1822
+ >>> am = np.ma.array(a, mask=m)
1823
+ >>> np.array(am[~am.mask])
1824
+ array([0, 1, 2, 3, 6])
1825
+
1826
+ >>> np.ma.notmasked_edges(am)
1827
+ array([0, 6])
1828
+
1829
+ """
1830
+ a = asarray(a)
1831
+ if axis is None or a.ndim == 1:
1832
+ return flatnotmasked_edges(a)
1833
+ m = getmaskarray(a)
1834
+ idx = array(np.indices(a.shape), mask=np.asarray([m] * a.ndim))
1835
+ return [tuple([idx[i].min(axis).compressed() for i in range(a.ndim)]),
1836
+ tuple([idx[i].max(axis).compressed() for i in range(a.ndim)]), ]
1837
+
1838
+
1839
+ def flatnotmasked_contiguous(a):
1840
+ """
1841
+ Find contiguous unmasked data in a masked array.
1842
+
1843
+ Parameters
1844
+ ----------
1845
+ a : array_like
1846
+ The input array.
1847
+
1848
+ Returns
1849
+ -------
1850
+ slice_list : list
1851
+ A sorted sequence of `slice` objects (start index, end index).
1852
+
1853
+ .. versionchanged:: 1.15.0
1854
+ Now returns an empty list instead of None for a fully masked array
1855
+
1856
+ See Also
1857
+ --------
1858
+ flatnotmasked_edges, notmasked_contiguous, notmasked_edges
1859
+ clump_masked, clump_unmasked
1860
+
1861
+ Notes
1862
+ -----
1863
+ Only accepts 2-D arrays at most.
1864
+
1865
+ Examples
1866
+ --------
1867
+ >>> a = np.ma.arange(10)
1868
+ >>> np.ma.flatnotmasked_contiguous(a)
1869
+ [slice(0, 10, None)]
1870
+
1871
+ >>> mask = (a < 3) | (a > 8) | (a == 5)
1872
+ >>> a[mask] = np.ma.masked
1873
+ >>> np.array(a[~a.mask])
1874
+ array([3, 4, 6, 7, 8])
1875
+
1876
+ >>> np.ma.flatnotmasked_contiguous(a)
1877
+ [slice(3, 5, None), slice(6, 9, None)]
1878
+ >>> a[:] = np.ma.masked
1879
+ >>> np.ma.flatnotmasked_contiguous(a)
1880
+ []
1881
+
1882
+ """
1883
+ m = getmask(a)
1884
+ if m is nomask:
1885
+ return [slice(0, a.size)]
1886
+ i = 0
1887
+ result = []
1888
+ for (k, g) in itertools.groupby(m.ravel()):
1889
+ n = len(list(g))
1890
+ if not k:
1891
+ result.append(slice(i, i + n))
1892
+ i += n
1893
+ return result
1894
+
1895
+
1896
+ def notmasked_contiguous(a, axis=None):
1897
+ """
1898
+ Find contiguous unmasked data in a masked array along the given axis.
1899
+
1900
+ Parameters
1901
+ ----------
1902
+ a : array_like
1903
+ The input array.
1904
+ axis : int, optional
1905
+ Axis along which to perform the operation.
1906
+ If None (default), applies to a flattened version of the array, and this
1907
+ is the same as `flatnotmasked_contiguous`.
1908
+
1909
+ Returns
1910
+ -------
1911
+ endpoints : list
1912
+ A list of slices (start and end indexes) of unmasked indexes
1913
+ in the array.
1914
+
1915
+ If the input is 2d and axis is specified, the result is a list of lists.
1916
+
1917
+ See Also
1918
+ --------
1919
+ flatnotmasked_edges, flatnotmasked_contiguous, notmasked_edges
1920
+ clump_masked, clump_unmasked
1921
+
1922
+ Notes
1923
+ -----
1924
+ Only accepts 2-D arrays at most.
1925
+
1926
+ Examples
1927
+ --------
1928
+ >>> a = np.arange(12).reshape((3, 4))
1929
+ >>> mask = np.zeros_like(a)
1930
+ >>> mask[1:, :-1] = 1; mask[0, 1] = 1; mask[-1, 0] = 0
1931
+ >>> ma = np.ma.array(a, mask=mask)
1932
+ >>> ma
1933
+ masked_array(
1934
+ data=[[0, --, 2, 3],
1935
+ [--, --, --, 7],
1936
+ [8, --, --, 11]],
1937
+ mask=[[False, True, False, False],
1938
+ [ True, True, True, False],
1939
+ [False, True, True, False]],
1940
+ fill_value=999999)
1941
+ >>> np.array(ma[~ma.mask])
1942
+ array([ 0, 2, 3, 7, 8, 11])
1943
+
1944
+ >>> np.ma.notmasked_contiguous(ma)
1945
+ [slice(0, 1, None), slice(2, 4, None), slice(7, 9, None), slice(11, 12, None)]
1946
+
1947
+ >>> np.ma.notmasked_contiguous(ma, axis=0)
1948
+ [[slice(0, 1, None), slice(2, 3, None)], [], [slice(0, 1, None)], [slice(0, 3, None)]]
1949
+
1950
+ >>> np.ma.notmasked_contiguous(ma, axis=1)
1951
+ [[slice(0, 1, None), slice(2, 4, None)], [slice(3, 4, None)], [slice(0, 1, None), slice(3, 4, None)]]
1952
+
1953
+ """
1954
+ a = asarray(a)
1955
+ nd = a.ndim
1956
+ if nd > 2:
1957
+ raise NotImplementedError("Currently limited to at most 2D array.")
1958
+ if axis is None or nd == 1:
1959
+ return flatnotmasked_contiguous(a)
1960
+ #
1961
+ result = []
1962
+ #
1963
+ other = (axis + 1) % 2
1964
+ idx = [0, 0]
1965
+ idx[axis] = slice(None, None)
1966
+ #
1967
+ for i in range(a.shape[other]):
1968
+ idx[other] = i
1969
+ result.append(flatnotmasked_contiguous(a[tuple(idx)]))
1970
+ return result
1971
+
1972
+
1973
+ def _ezclump(mask):
1974
+ """
1975
+ Finds the clumps (groups of data with the same values) for a 1D bool array.
1976
+
1977
+ Returns a series of slices.
1978
+ """
1979
+ if mask.ndim > 1:
1980
+ mask = mask.ravel()
1981
+ idx = (mask[1:] ^ mask[:-1]).nonzero()
1982
+ idx = idx[0] + 1
1983
+
1984
+ if mask[0]:
1985
+ if len(idx) == 0:
1986
+ return [slice(0, mask.size)]
1987
+
1988
+ r = [slice(0, idx[0])]
1989
+ r.extend((slice(left, right)
1990
+ for left, right in zip(idx[1:-1:2], idx[2::2])))
1991
+ else:
1992
+ if len(idx) == 0:
1993
+ return []
1994
+
1995
+ r = [slice(left, right) for left, right in zip(idx[:-1:2], idx[1::2])]
1996
+
1997
+ if mask[-1]:
1998
+ r.append(slice(idx[-1], mask.size))
1999
+ return r
2000
+
2001
+
2002
+ def clump_unmasked(a):
2003
+ """
2004
+ Return list of slices corresponding to the unmasked clumps of a 1-D array.
2005
+ (A "clump" is defined as a contiguous region of the array).
2006
+
2007
+ Parameters
2008
+ ----------
2009
+ a : ndarray
2010
+ A one-dimensional masked array.
2011
+
2012
+ Returns
2013
+ -------
2014
+ slices : list of slice
2015
+ The list of slices, one for each continuous region of unmasked
2016
+ elements in `a`.
2017
+
2018
+ Notes
2019
+ -----
2020
+ .. versionadded:: 1.4.0
2021
+
2022
+ See Also
2023
+ --------
2024
+ flatnotmasked_edges, flatnotmasked_contiguous, notmasked_edges
2025
+ notmasked_contiguous, clump_masked
2026
+
2027
+ Examples
2028
+ --------
2029
+ >>> a = np.ma.masked_array(np.arange(10))
2030
+ >>> a[[0, 1, 2, 6, 8, 9]] = np.ma.masked
2031
+ >>> np.ma.clump_unmasked(a)
2032
+ [slice(3, 6, None), slice(7, 8, None)]
2033
+
2034
+ """
2035
+ mask = getattr(a, '_mask', nomask)
2036
+ if mask is nomask:
2037
+ return [slice(0, a.size)]
2038
+ return _ezclump(~mask)
2039
+
2040
+
2041
+ def clump_masked(a):
2042
+ """
2043
+ Returns a list of slices corresponding to the masked clumps of a 1-D array.
2044
+ (A "clump" is defined as a contiguous region of the array).
2045
+
2046
+ Parameters
2047
+ ----------
2048
+ a : ndarray
2049
+ A one-dimensional masked array.
2050
+
2051
+ Returns
2052
+ -------
2053
+ slices : list of slice
2054
+ The list of slices, one for each continuous region of masked elements
2055
+ in `a`.
2056
+
2057
+ Notes
2058
+ -----
2059
+ .. versionadded:: 1.4.0
2060
+
2061
+ See Also
2062
+ --------
2063
+ flatnotmasked_edges, flatnotmasked_contiguous, notmasked_edges
2064
+ notmasked_contiguous, clump_unmasked
2065
+
2066
+ Examples
2067
+ --------
2068
+ >>> a = np.ma.masked_array(np.arange(10))
2069
+ >>> a[[0, 1, 2, 6, 8, 9]] = np.ma.masked
2070
+ >>> np.ma.clump_masked(a)
2071
+ [slice(0, 3, None), slice(6, 7, None), slice(8, 10, None)]
2072
+
2073
+ """
2074
+ mask = ma.getmask(a)
2075
+ if mask is nomask:
2076
+ return []
2077
+ return _ezclump(mask)
2078
+
2079
+
2080
+ ###############################################################################
2081
+ # Polynomial fit #
2082
+ ###############################################################################
2083
+
2084
+
2085
+ def vander(x, n=None):
2086
+ """
2087
+ Masked values in the input array result in rows of zeros.
2088
+
2089
+ """
2090
+ _vander = np.vander(x, n)
2091
+ m = getmask(x)
2092
+ if m is not nomask:
2093
+ _vander[m] = 0
2094
+ return _vander
2095
+
2096
+ vander.__doc__ = ma.doc_note(np.vander.__doc__, vander.__doc__)
2097
+
2098
+
2099
+ def polyfit(x, y, deg, rcond=None, full=False, w=None, cov=False):
2100
+ """
2101
+ Any masked values in x is propagated in y, and vice-versa.
2102
+
2103
+ """
2104
+ x = asarray(x)
2105
+ y = asarray(y)
2106
+
2107
+ m = getmask(x)
2108
+ if y.ndim == 1:
2109
+ m = mask_or(m, getmask(y))
2110
+ elif y.ndim == 2:
2111
+ my = getmask(mask_rows(y))
2112
+ if my is not nomask:
2113
+ m = mask_or(m, my[:, 0])
2114
+ else:
2115
+ raise TypeError("Expected a 1D or 2D array for y!")
2116
+
2117
+ if w is not None:
2118
+ w = asarray(w)
2119
+ if w.ndim != 1:
2120
+ raise TypeError("expected a 1-d array for weights")
2121
+ if w.shape[0] != y.shape[0]:
2122
+ raise TypeError("expected w and y to have the same length")
2123
+ m = mask_or(m, getmask(w))
2124
+
2125
+ if m is not nomask:
2126
+ not_m = ~m
2127
+ if w is not None:
2128
+ w = w[not_m]
2129
+ return np.polyfit(x[not_m], y[not_m], deg, rcond, full, w, cov)
2130
+ else:
2131
+ return np.polyfit(x, y, deg, rcond, full, w, cov)
2132
+
2133
+ polyfit.__doc__ = ma.doc_note(np.polyfit.__doc__, polyfit.__doc__)