Coverage for /home/martinb/.local/share/virtualenvs/camcops/lib/python3.6/site-packages/numpy/core/_methods.py : 38%

Hot-keys on this page
r m x p toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
1"""
2Array methods which are called by both the C-code for the method
3and the Python code for the NumPy-namespace function
5"""
6import warnings
8from numpy.core import multiarray as mu
9from numpy.core import umath as um
10from numpy.core._asarray import asanyarray
11from numpy.core import numerictypes as nt
12from numpy.core import _exceptions
13from numpy._globals import _NoValue
14from numpy.compat import pickle, os_fspath, contextlib_nullcontext
16# save those O(100) nanoseconds!
17umr_maximum = um.maximum.reduce
18umr_minimum = um.minimum.reduce
19umr_sum = um.add.reduce
20umr_prod = um.multiply.reduce
21umr_any = um.logical_or.reduce
22umr_all = um.logical_and.reduce
24# Complex types to -> (2,)float view for fast-path computation in _var()
25_complex_to_float = {
26 nt.dtype(nt.csingle) : nt.dtype(nt.single),
27 nt.dtype(nt.cdouble) : nt.dtype(nt.double),
28}
29# Special case for windows: ensure double takes precedence
30if nt.dtype(nt.longdouble) != nt.dtype(nt.double):
31 _complex_to_float.update({
32 nt.dtype(nt.clongdouble) : nt.dtype(nt.longdouble),
33 })
35# avoid keyword arguments to speed up parsing, saves about 15%-20% for very
36# small reductions
37def _amax(a, axis=None, out=None, keepdims=False,
38 initial=_NoValue, where=True):
39 return umr_maximum(a, axis, None, out, keepdims, initial, where)
41def _amin(a, axis=None, out=None, keepdims=False,
42 initial=_NoValue, where=True):
43 return umr_minimum(a, axis, None, out, keepdims, initial, where)
45def _sum(a, axis=None, dtype=None, out=None, keepdims=False,
46 initial=_NoValue, where=True):
47 return umr_sum(a, axis, dtype, out, keepdims, initial, where)
49def _prod(a, axis=None, dtype=None, out=None, keepdims=False,
50 initial=_NoValue, where=True):
51 return umr_prod(a, axis, dtype, out, keepdims, initial, where)
53def _any(a, axis=None, dtype=None, out=None, keepdims=False):
54 return umr_any(a, axis, dtype, out, keepdims)
56def _all(a, axis=None, dtype=None, out=None, keepdims=False):
57 return umr_all(a, axis, dtype, out, keepdims)
59def _count_reduce_items(arr, axis):
60 if axis is None:
61 axis = tuple(range(arr.ndim))
62 if not isinstance(axis, tuple):
63 axis = (axis,)
64 items = 1
65 for ax in axis:
66 items *= arr.shape[mu.normalize_axis_index(ax, arr.ndim)]
67 return items
69# Numpy 1.17.0, 2019-02-24
70# Various clip behavior deprecations, marked with _clip_dep as a prefix.
72def _clip_dep_is_scalar_nan(a):
73 # guarded to protect circular imports
74 from numpy.core.fromnumeric import ndim
75 if ndim(a) != 0:
76 return False
77 try:
78 return um.isnan(a)
79 except TypeError:
80 return False
82def _clip_dep_is_byte_swapped(a):
83 if isinstance(a, mu.ndarray):
84 return not a.dtype.isnative
85 return False
87def _clip_dep_invoke_with_casting(ufunc, *args, out=None, casting=None, **kwargs):
88 # normal path
89 if casting is not None:
90 return ufunc(*args, out=out, casting=casting, **kwargs)
92 # try to deal with broken casting rules
93 try:
94 return ufunc(*args, out=out, **kwargs)
95 except _exceptions._UFuncOutputCastingError as e:
96 # Numpy 1.17.0, 2019-02-24
97 warnings.warn(
98 "Converting the output of clip from {!r} to {!r} is deprecated. "
99 "Pass `casting=\"unsafe\"` explicitly to silence this warning, or "
100 "correct the type of the variables.".format(e.from_, e.to),
101 DeprecationWarning,
102 stacklevel=2
103 )
104 return ufunc(*args, out=out, casting="unsafe", **kwargs)
106def _clip(a, min=None, max=None, out=None, *, casting=None, **kwargs):
107 if min is None and max is None:
108 raise ValueError("One of max or min must be given")
110 # Numpy 1.17.0, 2019-02-24
111 # This deprecation probably incurs a substantial slowdown for small arrays,
112 # it will be good to get rid of it.
113 if not _clip_dep_is_byte_swapped(a) and not _clip_dep_is_byte_swapped(out):
114 using_deprecated_nan = False
115 if _clip_dep_is_scalar_nan(min):
116 min = -float('inf')
117 using_deprecated_nan = True
118 if _clip_dep_is_scalar_nan(max):
119 max = float('inf')
120 using_deprecated_nan = True
121 if using_deprecated_nan:
122 warnings.warn(
123 "Passing `np.nan` to mean no clipping in np.clip has always "
124 "been unreliable, and is now deprecated. "
125 "In future, this will always return nan, like it already does "
126 "when min or max are arrays that contain nan. "
127 "To skip a bound, pass either None or an np.inf of an "
128 "appropriate sign.",
129 DeprecationWarning,
130 stacklevel=2
131 )
133 if min is None:
134 return _clip_dep_invoke_with_casting(
135 um.minimum, a, max, out=out, casting=casting, **kwargs)
136 elif max is None:
137 return _clip_dep_invoke_with_casting(
138 um.maximum, a, min, out=out, casting=casting, **kwargs)
139 else:
140 return _clip_dep_invoke_with_casting(
141 um.clip, a, min, max, out=out, casting=casting, **kwargs)
143def _mean(a, axis=None, dtype=None, out=None, keepdims=False):
144 arr = asanyarray(a)
146 is_float16_result = False
147 rcount = _count_reduce_items(arr, axis)
148 # Make this warning show up first
149 if rcount == 0:
150 warnings.warn("Mean of empty slice.", RuntimeWarning, stacklevel=2)
152 # Cast bool, unsigned int, and int to float64 by default
153 if dtype is None:
154 if issubclass(arr.dtype.type, (nt.integer, nt.bool_)):
155 dtype = mu.dtype('f8')
156 elif issubclass(arr.dtype.type, nt.float16):
157 dtype = mu.dtype('f4')
158 is_float16_result = True
160 ret = umr_sum(arr, axis, dtype, out, keepdims)
161 if isinstance(ret, mu.ndarray):
162 ret = um.true_divide(
163 ret, rcount, out=ret, casting='unsafe', subok=False)
164 if is_float16_result and out is None:
165 ret = arr.dtype.type(ret)
166 elif hasattr(ret, 'dtype'):
167 if is_float16_result:
168 ret = arr.dtype.type(ret / rcount)
169 else:
170 ret = ret.dtype.type(ret / rcount)
171 else:
172 ret = ret / rcount
174 return ret
176def _var(a, axis=None, dtype=None, out=None, ddof=0, keepdims=False):
177 arr = asanyarray(a)
179 rcount = _count_reduce_items(arr, axis)
180 # Make this warning show up on top.
181 if ddof >= rcount:
182 warnings.warn("Degrees of freedom <= 0 for slice", RuntimeWarning,
183 stacklevel=2)
185 # Cast bool, unsigned int, and int to float64 by default
186 if dtype is None and issubclass(arr.dtype.type, (nt.integer, nt.bool_)):
187 dtype = mu.dtype('f8')
189 # Compute the mean.
190 # Note that if dtype is not of inexact type then arraymean will
191 # not be either.
192 arrmean = umr_sum(arr, axis, dtype, keepdims=True)
193 if isinstance(arrmean, mu.ndarray):
194 arrmean = um.true_divide(
195 arrmean, rcount, out=arrmean, casting='unsafe', subok=False)
196 else:
197 arrmean = arrmean.dtype.type(arrmean / rcount)
199 # Compute sum of squared deviations from mean
200 # Note that x may not be inexact and that we need it to be an array,
201 # not a scalar.
202 x = asanyarray(arr - arrmean)
204 if issubclass(arr.dtype.type, (nt.floating, nt.integer)):
205 x = um.multiply(x, x, out=x)
206 # Fast-paths for built-in complex types
207 elif x.dtype in _complex_to_float:
208 xv = x.view(dtype=(_complex_to_float[x.dtype], (2,)))
209 um.multiply(xv, xv, out=xv)
210 x = um.add(xv[..., 0], xv[..., 1], out=x.real).real
211 # Most general case; includes handling object arrays containing imaginary
212 # numbers and complex types with non-native byteorder
213 else:
214 x = um.multiply(x, um.conjugate(x), out=x).real
216 ret = umr_sum(x, axis, dtype, out, keepdims)
218 # Compute degrees of freedom and make sure it is not negative.
219 rcount = max([rcount - ddof, 0])
221 # divide by degrees of freedom
222 if isinstance(ret, mu.ndarray):
223 ret = um.true_divide(
224 ret, rcount, out=ret, casting='unsafe', subok=False)
225 elif hasattr(ret, 'dtype'):
226 ret = ret.dtype.type(ret / rcount)
227 else:
228 ret = ret / rcount
230 return ret
232def _std(a, axis=None, dtype=None, out=None, ddof=0, keepdims=False):
233 ret = _var(a, axis=axis, dtype=dtype, out=out, ddof=ddof,
234 keepdims=keepdims)
236 if isinstance(ret, mu.ndarray):
237 ret = um.sqrt(ret, out=ret)
238 elif hasattr(ret, 'dtype'):
239 ret = ret.dtype.type(um.sqrt(ret))
240 else:
241 ret = um.sqrt(ret)
243 return ret
245def _ptp(a, axis=None, out=None, keepdims=False):
246 return um.subtract(
247 umr_maximum(a, axis, None, out, keepdims),
248 umr_minimum(a, axis, None, None, keepdims),
249 out
250 )
252def _dump(self, file, protocol=2):
253 if hasattr(file, 'write'):
254 ctx = contextlib_nullcontext(file)
255 else:
256 ctx = open(os_fspath(file), "wb")
257 with ctx as f:
258 pickle.dump(self, f, protocol=protocol)
260def _dumps(self, protocol=2):
261 return pickle.dumps(self, protocol=protocol)