_nanfunctions_impl.py 70 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006
  1. """
  2. Functions that ignore NaN.
  3. Functions
  4. ---------
  5. - `nanmin` -- minimum non-NaN value
  6. - `nanmax` -- maximum non-NaN value
  7. - `nanargmin` -- index of minimum non-NaN value
  8. - `nanargmax` -- index of maximum non-NaN value
  9. - `nansum` -- sum of non-NaN values
  10. - `nanprod` -- product of non-NaN values
  11. - `nancumsum` -- cumulative sum of non-NaN values
  12. - `nancumprod` -- cumulative product of non-NaN values
  13. - `nanmean` -- mean of non-NaN values
  14. - `nanvar` -- variance of non-NaN values
  15. - `nanstd` -- standard deviation of non-NaN values
  16. - `nanmedian` -- median of non-NaN values
  17. - `nanquantile` -- qth quantile of non-NaN values
  18. - `nanpercentile` -- qth percentile of non-NaN values
  19. """
  20. import functools
  21. import warnings
  22. import numpy as np
  23. import numpy._core.numeric as _nx
  24. from numpy._core import overrides
  25. from numpy.lib import _function_base_impl as fnb
  26. from numpy.lib._function_base_impl import _weights_are_valid
  27. array_function_dispatch = functools.partial(
  28. overrides.array_function_dispatch, module='numpy')
  29. __all__ = [
  30. 'nansum', 'nanmax', 'nanmin', 'nanargmax', 'nanargmin', 'nanmean',
  31. 'nanmedian', 'nanpercentile', 'nanvar', 'nanstd', 'nanprod',
  32. 'nancumsum', 'nancumprod', 'nanquantile'
  33. ]
  34. def _nan_mask(a, out=None):
  35. """
  36. Parameters
  37. ----------
  38. a : array-like
  39. Input array with at least 1 dimension.
  40. out : ndarray, optional
  41. Alternate output array in which to place the result. The default
  42. is ``None``; if provided, it must have the same shape as the
  43. expected output and will prevent the allocation of a new array.
  44. Returns
  45. -------
  46. y : bool ndarray or True
  47. A bool array where ``np.nan`` positions are marked with ``False``
  48. and other positions are marked with ``True``. If the type of ``a``
  49. is such that it can't possibly contain ``np.nan``, returns ``True``.
  50. """
  51. # we assume that a is an array for this private function
  52. if a.dtype.kind not in 'fc':
  53. return True
  54. y = np.isnan(a, out=out)
  55. y = np.invert(y, out=y)
  56. return y
  57. def _replace_nan(a, val):
  58. """
  59. If `a` is of inexact type, make a copy of `a`, replace NaNs with
  60. the `val` value, and return the copy together with a boolean mask
  61. marking the locations where NaNs were present. If `a` is not of
  62. inexact type, do nothing and return `a` together with a mask of None.
  63. Note that scalars will end up as array scalars, which is important
  64. for using the result as the value of the out argument in some
  65. operations.
  66. Parameters
  67. ----------
  68. a : array-like
  69. Input array.
  70. val : float
  71. NaN values are set to val before doing the operation.
  72. Returns
  73. -------
  74. y : ndarray
  75. If `a` is of inexact type, return a copy of `a` with the NaNs
  76. replaced by the fill value, otherwise return `a`.
  77. mask: {bool, None}
  78. If `a` is of inexact type, return a boolean mask marking locations of
  79. NaNs, otherwise return None.
  80. """
  81. a = np.asanyarray(a)
  82. if a.dtype == np.object_:
  83. # object arrays do not support `isnan` (gh-9009), so make a guess
  84. mask = np.not_equal(a, a, dtype=bool)
  85. elif issubclass(a.dtype.type, np.inexact):
  86. mask = np.isnan(a)
  87. else:
  88. mask = None
  89. if mask is not None:
  90. a = np.array(a, subok=True, copy=True)
  91. np.copyto(a, val, where=mask)
  92. return a, mask
  93. def _copyto(a, val, mask):
  94. """
  95. Replace values in `a` with NaN where `mask` is True. This differs from
  96. copyto in that it will deal with the case where `a` is a numpy scalar.
  97. Parameters
  98. ----------
  99. a : ndarray or numpy scalar
  100. Array or numpy scalar some of whose values are to be replaced
  101. by val.
  102. val : numpy scalar
  103. Value used a replacement.
  104. mask : ndarray, scalar
  105. Boolean array. Where True the corresponding element of `a` is
  106. replaced by `val`. Broadcasts.
  107. Returns
  108. -------
  109. res : ndarray, scalar
  110. Array with elements replaced or scalar `val`.
  111. """
  112. if isinstance(a, np.ndarray):
  113. np.copyto(a, val, where=mask, casting='unsafe')
  114. else:
  115. a = a.dtype.type(val)
  116. return a
  117. def _remove_nan_1d(arr1d, second_arr1d=None, overwrite_input=False):
  118. """
  119. Equivalent to arr1d[~arr1d.isnan()], but in a different order
  120. Presumably faster as it incurs fewer copies
  121. Parameters
  122. ----------
  123. arr1d : ndarray
  124. Array to remove nans from
  125. second_arr1d : ndarray or None
  126. A second array which will have the same positions removed as arr1d.
  127. overwrite_input : bool
  128. True if `arr1d` can be modified in place
  129. Returns
  130. -------
  131. res : ndarray
  132. Array with nan elements removed
  133. second_res : ndarray or None
  134. Second array with nan element positions of first array removed.
  135. overwrite_input : bool
  136. True if `res` can be modified in place, given the constraint on the
  137. input
  138. """
  139. if arr1d.dtype == object:
  140. # object arrays do not support `isnan` (gh-9009), so make a guess
  141. c = np.not_equal(arr1d, arr1d, dtype=bool)
  142. else:
  143. c = np.isnan(arr1d)
  144. s = np.nonzero(c)[0]
  145. if s.size == arr1d.size:
  146. warnings.warn("All-NaN slice encountered", RuntimeWarning,
  147. stacklevel=6)
  148. if second_arr1d is None:
  149. return arr1d[:0], None, True
  150. else:
  151. return arr1d[:0], second_arr1d[:0], True
  152. elif s.size == 0:
  153. return arr1d, second_arr1d, overwrite_input
  154. else:
  155. if not overwrite_input:
  156. arr1d = arr1d.copy()
  157. # select non-nans at end of array
  158. enonan = arr1d[-s.size:][~c[-s.size:]]
  159. # fill nans in beginning of array with non-nans of end
  160. arr1d[s[:enonan.size]] = enonan
  161. if second_arr1d is None:
  162. return arr1d[:-s.size], None, True
  163. else:
  164. if not overwrite_input:
  165. second_arr1d = second_arr1d.copy()
  166. enonan = second_arr1d[-s.size:][~c[-s.size:]]
  167. second_arr1d[s[:enonan.size]] = enonan
  168. return arr1d[:-s.size], second_arr1d[:-s.size], True
  169. def _divide_by_count(a, b, out=None):
  170. """
  171. Compute a/b ignoring invalid results. If `a` is an array the division
  172. is done in place. If `a` is a scalar, then its type is preserved in the
  173. output. If out is None, then a is used instead so that the division
  174. is in place. Note that this is only called with `a` an inexact type.
  175. Parameters
  176. ----------
  177. a : {ndarray, numpy scalar}
  178. Numerator. Expected to be of inexact type but not checked.
  179. b : {ndarray, numpy scalar}
  180. Denominator.
  181. out : ndarray, optional
  182. Alternate output array in which to place the result. The default
  183. is ``None``; if provided, it must have the same shape as the
  184. expected output, but the type will be cast if necessary.
  185. Returns
  186. -------
  187. ret : {ndarray, numpy scalar}
  188. The return value is a/b. If `a` was an ndarray the division is done
  189. in place. If `a` is a numpy scalar, the division preserves its type.
  190. """
  191. with np.errstate(invalid='ignore', divide='ignore'):
  192. if isinstance(a, np.ndarray):
  193. if out is None:
  194. return np.divide(a, b, out=a, casting='unsafe')
  195. else:
  196. return np.divide(a, b, out=out, casting='unsafe')
  197. elif out is None:
  198. # Precaution against reduced object arrays
  199. try:
  200. return a.dtype.type(a / b)
  201. except AttributeError:
  202. return a / b
  203. else:
  204. # This is questionable, but currently a numpy scalar can
  205. # be output to a zero dimensional array.
  206. return np.divide(a, b, out=out, casting='unsafe')
  207. def _nanmin_dispatcher(a, axis=None, out=None, keepdims=None,
  208. initial=None, where=None):
  209. return (a, out)
  210. @array_function_dispatch(_nanmin_dispatcher)
  211. def nanmin(a, axis=None, out=None, keepdims=np._NoValue, initial=np._NoValue,
  212. where=np._NoValue):
  213. """
  214. Return minimum of an array or minimum along an axis, ignoring any NaNs.
  215. When all-NaN slices are encountered a ``RuntimeWarning`` is raised and
  216. Nan is returned for that slice.
  217. Parameters
  218. ----------
  219. a : array_like
  220. Array containing numbers whose minimum is desired. If `a` is not an
  221. array, a conversion is attempted.
  222. axis : {int, tuple of int, None}, optional
  223. Axis or axes along which the minimum is computed. The default is to compute
  224. the minimum of the flattened array.
  225. out : ndarray, optional
  226. Alternate output array in which to place the result. The default
  227. is ``None``; if provided, it must have the same shape as the
  228. expected output, but the type will be cast if necessary. See
  229. :ref:`ufuncs-output-type` for more details.
  230. keepdims : bool, optional
  231. If this is set to True, the axes which are reduced are left
  232. in the result as dimensions with size one. With this option,
  233. the result will broadcast correctly against the original `a`.
  234. If the value is anything but the default, then
  235. `keepdims` will be passed through to the `min` method
  236. of sub-classes of `ndarray`. If the sub-classes methods
  237. does not implement `keepdims` any exceptions will be raised.
  238. initial : scalar, optional
  239. The maximum value of an output element. Must be present to allow
  240. computation on empty slice. See `~numpy.ufunc.reduce` for details.
  241. .. versionadded:: 1.22.0
  242. where : array_like of bool, optional
  243. Elements to compare for the minimum. See `~numpy.ufunc.reduce`
  244. for details.
  245. .. versionadded:: 1.22.0
  246. Returns
  247. -------
  248. nanmin : ndarray
  249. An array with the same shape as `a`, with the specified axis
  250. removed. If `a` is a 0-d array, or if axis is None, an ndarray
  251. scalar is returned. The same dtype as `a` is returned.
  252. See Also
  253. --------
  254. nanmax :
  255. The maximum value of an array along a given axis, ignoring any NaNs.
  256. amin :
  257. The minimum value of an array along a given axis, propagating any NaNs.
  258. fmin :
  259. Element-wise minimum of two arrays, ignoring any NaNs.
  260. minimum :
  261. Element-wise minimum of two arrays, propagating any NaNs.
  262. isnan :
  263. Shows which elements are Not a Number (NaN).
  264. isfinite:
  265. Shows which elements are neither NaN nor infinity.
  266. amax, fmax, maximum
  267. Notes
  268. -----
  269. NumPy uses the IEEE Standard for Binary Floating-Point for Arithmetic
  270. (IEEE 754). This means that Not a Number is not equivalent to infinity.
  271. Positive infinity is treated as a very large number and negative
  272. infinity is treated as a very small (i.e. negative) number.
  273. If the input has a integer type the function is equivalent to np.min.
  274. Examples
  275. --------
  276. >>> import numpy as np
  277. >>> a = np.array([[1, 2], [3, np.nan]])
  278. >>> np.nanmin(a)
  279. 1.0
  280. >>> np.nanmin(a, axis=0)
  281. array([1., 2.])
  282. >>> np.nanmin(a, axis=1)
  283. array([1., 3.])
  284. When positive infinity and negative infinity are present:
  285. >>> np.nanmin([1, 2, np.nan, np.inf])
  286. 1.0
  287. >>> np.nanmin([1, 2, np.nan, -np.inf])
  288. -inf
  289. """
  290. kwargs = {}
  291. if keepdims is not np._NoValue:
  292. kwargs['keepdims'] = keepdims
  293. if initial is not np._NoValue:
  294. kwargs['initial'] = initial
  295. if where is not np._NoValue:
  296. kwargs['where'] = where
  297. if (type(a) is np.ndarray or type(a) is np.memmap) and a.dtype != np.object_:
  298. # Fast, but not safe for subclasses of ndarray, or object arrays,
  299. # which do not implement isnan (gh-9009), or fmin correctly (gh-8975)
  300. res = np.fmin.reduce(a, axis=axis, out=out, **kwargs)
  301. if np.isnan(res).any():
  302. warnings.warn("All-NaN slice encountered", RuntimeWarning,
  303. stacklevel=2)
  304. else:
  305. # Slow, but safe for subclasses of ndarray
  306. a, mask = _replace_nan(a, +np.inf)
  307. res = np.amin(a, axis=axis, out=out, **kwargs)
  308. if mask is None:
  309. return res
  310. # Check for all-NaN axis
  311. kwargs.pop("initial", None)
  312. mask = np.all(mask, axis=axis, **kwargs)
  313. if np.any(mask):
  314. res = _copyto(res, np.nan, mask)
  315. warnings.warn("All-NaN axis encountered", RuntimeWarning,
  316. stacklevel=2)
  317. return res
  318. def _nanmax_dispatcher(a, axis=None, out=None, keepdims=None,
  319. initial=None, where=None):
  320. return (a, out)
  321. @array_function_dispatch(_nanmax_dispatcher)
  322. def nanmax(a, axis=None, out=None, keepdims=np._NoValue, initial=np._NoValue,
  323. where=np._NoValue):
  324. """
  325. Return the maximum of an array or maximum along an axis, ignoring any
  326. NaNs. When all-NaN slices are encountered a ``RuntimeWarning`` is
  327. raised and NaN is returned for that slice.
  328. Parameters
  329. ----------
  330. a : array_like
  331. Array containing numbers whose maximum is desired. If `a` is not an
  332. array, a conversion is attempted.
  333. axis : {int, tuple of int, None}, optional
  334. Axis or axes along which the maximum is computed. The default is to compute
  335. the maximum of the flattened array.
  336. out : ndarray, optional
  337. Alternate output array in which to place the result. The default
  338. is ``None``; if provided, it must have the same shape as the
  339. expected output, but the type will be cast if necessary. See
  340. :ref:`ufuncs-output-type` for more details.
  341. keepdims : bool, optional
  342. If this is set to True, the axes which are reduced are left
  343. in the result as dimensions with size one. With this option,
  344. the result will broadcast correctly against the original `a`.
  345. If the value is anything but the default, then
  346. `keepdims` will be passed through to the `max` method
  347. of sub-classes of `ndarray`. If the sub-classes methods
  348. does not implement `keepdims` any exceptions will be raised.
  349. initial : scalar, optional
  350. The minimum value of an output element. Must be present to allow
  351. computation on empty slice. See `~numpy.ufunc.reduce` for details.
  352. .. versionadded:: 1.22.0
  353. where : array_like of bool, optional
  354. Elements to compare for the maximum. See `~numpy.ufunc.reduce`
  355. for details.
  356. .. versionadded:: 1.22.0
  357. Returns
  358. -------
  359. nanmax : ndarray
  360. An array with the same shape as `a`, with the specified axis removed.
  361. If `a` is a 0-d array, or if axis is None, an ndarray scalar is
  362. returned. The same dtype as `a` is returned.
  363. See Also
  364. --------
  365. nanmin :
  366. The minimum value of an array along a given axis, ignoring any NaNs.
  367. amax :
  368. The maximum value of an array along a given axis, propagating any NaNs.
  369. fmax :
  370. Element-wise maximum of two arrays, ignoring any NaNs.
  371. maximum :
  372. Element-wise maximum of two arrays, propagating any NaNs.
  373. isnan :
  374. Shows which elements are Not a Number (NaN).
  375. isfinite:
  376. Shows which elements are neither NaN nor infinity.
  377. amin, fmin, minimum
  378. Notes
  379. -----
  380. NumPy uses the IEEE Standard for Binary Floating-Point for Arithmetic
  381. (IEEE 754). This means that Not a Number is not equivalent to infinity.
  382. Positive infinity is treated as a very large number and negative
  383. infinity is treated as a very small (i.e. negative) number.
  384. If the input has a integer type the function is equivalent to np.max.
  385. Examples
  386. --------
  387. >>> import numpy as np
  388. >>> a = np.array([[1, 2], [3, np.nan]])
  389. >>> np.nanmax(a)
  390. 3.0
  391. >>> np.nanmax(a, axis=0)
  392. array([3., 2.])
  393. >>> np.nanmax(a, axis=1)
  394. array([2., 3.])
  395. When positive infinity and negative infinity are present:
  396. >>> np.nanmax([1, 2, np.nan, -np.inf])
  397. 2.0
  398. >>> np.nanmax([1, 2, np.nan, np.inf])
  399. inf
  400. """
  401. kwargs = {}
  402. if keepdims is not np._NoValue:
  403. kwargs['keepdims'] = keepdims
  404. if initial is not np._NoValue:
  405. kwargs['initial'] = initial
  406. if where is not np._NoValue:
  407. kwargs['where'] = where
  408. if (type(a) is np.ndarray or type(a) is np.memmap) and a.dtype != np.object_:
  409. # Fast, but not safe for subclasses of ndarray, or object arrays,
  410. # which do not implement isnan (gh-9009), or fmax correctly (gh-8975)
  411. res = np.fmax.reduce(a, axis=axis, out=out, **kwargs)
  412. if np.isnan(res).any():
  413. warnings.warn("All-NaN slice encountered", RuntimeWarning,
  414. stacklevel=2)
  415. else:
  416. # Slow, but safe for subclasses of ndarray
  417. a, mask = _replace_nan(a, -np.inf)
  418. res = np.amax(a, axis=axis, out=out, **kwargs)
  419. if mask is None:
  420. return res
  421. # Check for all-NaN axis
  422. kwargs.pop("initial", None)
  423. mask = np.all(mask, axis=axis, **kwargs)
  424. if np.any(mask):
  425. res = _copyto(res, np.nan, mask)
  426. warnings.warn("All-NaN axis encountered", RuntimeWarning,
  427. stacklevel=2)
  428. return res
  429. def _nanargmin_dispatcher(a, axis=None, out=None, *, keepdims=None):
  430. return (a,)
  431. @array_function_dispatch(_nanargmin_dispatcher)
  432. def nanargmin(a, axis=None, out=None, *, keepdims=np._NoValue):
  433. """
  434. Return the indices of the minimum values in the specified axis ignoring
  435. NaNs. For all-NaN slices ``ValueError`` is raised. Warning: the results
  436. cannot be trusted if a slice contains only NaNs and Infs.
  437. Parameters
  438. ----------
  439. a : array_like
  440. Input data.
  441. axis : int, optional
  442. Axis along which to operate. By default flattened input is used.
  443. out : array, optional
  444. If provided, the result will be inserted into this array. It should
  445. be of the appropriate shape and dtype.
  446. .. versionadded:: 1.22.0
  447. keepdims : bool, optional
  448. If this is set to True, the axes which are reduced are left
  449. in the result as dimensions with size one. With this option,
  450. the result will broadcast correctly against the array.
  451. .. versionadded:: 1.22.0
  452. Returns
  453. -------
  454. index_array : ndarray
  455. An array of indices or a single index value.
  456. See Also
  457. --------
  458. argmin, nanargmax
  459. Examples
  460. --------
  461. >>> import numpy as np
  462. >>> a = np.array([[np.nan, 4], [2, 3]])
  463. >>> np.argmin(a)
  464. 0
  465. >>> np.nanargmin(a)
  466. 2
  467. >>> np.nanargmin(a, axis=0)
  468. array([1, 1])
  469. >>> np.nanargmin(a, axis=1)
  470. array([1, 0])
  471. """
  472. a, mask = _replace_nan(a, np.inf)
  473. if mask is not None and mask.size:
  474. mask = np.all(mask, axis=axis)
  475. if np.any(mask):
  476. raise ValueError("All-NaN slice encountered")
  477. res = np.argmin(a, axis=axis, out=out, keepdims=keepdims)
  478. return res
  479. def _nanargmax_dispatcher(a, axis=None, out=None, *, keepdims=None):
  480. return (a,)
  481. @array_function_dispatch(_nanargmax_dispatcher)
  482. def nanargmax(a, axis=None, out=None, *, keepdims=np._NoValue):
  483. """
  484. Return the indices of the maximum values in the specified axis ignoring
  485. NaNs. For all-NaN slices ``ValueError`` is raised. Warning: the
  486. results cannot be trusted if a slice contains only NaNs and -Infs.
  487. Parameters
  488. ----------
  489. a : array_like
  490. Input data.
  491. axis : int, optional
  492. Axis along which to operate. By default flattened input is used.
  493. out : array, optional
  494. If provided, the result will be inserted into this array. It should
  495. be of the appropriate shape and dtype.
  496. .. versionadded:: 1.22.0
  497. keepdims : bool, optional
  498. If this is set to True, the axes which are reduced are left
  499. in the result as dimensions with size one. With this option,
  500. the result will broadcast correctly against the array.
  501. .. versionadded:: 1.22.0
  502. Returns
  503. -------
  504. index_array : ndarray
  505. An array of indices or a single index value.
  506. See Also
  507. --------
  508. argmax, nanargmin
  509. Examples
  510. --------
  511. >>> import numpy as np
  512. >>> a = np.array([[np.nan, 4], [2, 3]])
  513. >>> np.argmax(a)
  514. 0
  515. >>> np.nanargmax(a)
  516. 1
  517. >>> np.nanargmax(a, axis=0)
  518. array([1, 0])
  519. >>> np.nanargmax(a, axis=1)
  520. array([1, 1])
  521. """
  522. a, mask = _replace_nan(a, -np.inf)
  523. if mask is not None and mask.size:
  524. mask = np.all(mask, axis=axis)
  525. if np.any(mask):
  526. raise ValueError("All-NaN slice encountered")
  527. res = np.argmax(a, axis=axis, out=out, keepdims=keepdims)
  528. return res
  529. def _nansum_dispatcher(a, axis=None, dtype=None, out=None, keepdims=None,
  530. initial=None, where=None):
  531. return (a, out)
  532. @array_function_dispatch(_nansum_dispatcher)
  533. def nansum(a, axis=None, dtype=None, out=None, keepdims=np._NoValue,
  534. initial=np._NoValue, where=np._NoValue):
  535. """
  536. Return the sum of array elements over a given axis treating Not a
  537. Numbers (NaNs) as zero.
  538. In NumPy versions <= 1.9.0 Nan is returned for slices that are all-NaN or
  539. empty. In later versions zero is returned.
  540. Parameters
  541. ----------
  542. a : array_like
  543. Array containing numbers whose sum is desired. If `a` is not an
  544. array, a conversion is attempted.
  545. axis : {int, tuple of int, None}, optional
  546. Axis or axes along which the sum is computed. The default is to compute the
  547. sum of the flattened array.
  548. dtype : data-type, optional
  549. The type of the returned array and of the accumulator in which the
  550. elements are summed. By default, the dtype of `a` is used. An
  551. exception is when `a` has an integer type with less precision than
  552. the platform (u)intp. In that case, the default will be either
  553. (u)int32 or (u)int64 depending on whether the platform is 32 or 64
  554. bits. For inexact inputs, dtype must be inexact.
  555. out : ndarray, optional
  556. Alternate output array in which to place the result. The default
  557. is ``None``. If provided, it must have the same shape as the
  558. expected output, but the type will be cast if necessary. See
  559. :ref:`ufuncs-output-type` for more details. The casting of NaN to integer
  560. can yield unexpected results.
  561. keepdims : bool, optional
  562. If this is set to True, the axes which are reduced are left
  563. in the result as dimensions with size one. With this option,
  564. the result will broadcast correctly against the original `a`.
  565. If the value is anything but the default, then
  566. `keepdims` will be passed through to the `mean` or `sum` methods
  567. of sub-classes of `ndarray`. If the sub-classes methods
  568. does not implement `keepdims` any exceptions will be raised.
  569. initial : scalar, optional
  570. Starting value for the sum. See `~numpy.ufunc.reduce` for details.
  571. .. versionadded:: 1.22.0
  572. where : array_like of bool, optional
  573. Elements to include in the sum. See `~numpy.ufunc.reduce` for details.
  574. .. versionadded:: 1.22.0
  575. Returns
  576. -------
  577. nansum : ndarray.
  578. A new array holding the result is returned unless `out` is
  579. specified, in which it is returned. The result has the same
  580. size as `a`, and the same shape as `a` if `axis` is not None
  581. or `a` is a 1-d array.
  582. See Also
  583. --------
  584. numpy.sum : Sum across array propagating NaNs.
  585. isnan : Show which elements are NaN.
  586. isfinite : Show which elements are not NaN or +/-inf.
  587. Notes
  588. -----
  589. If both positive and negative infinity are present, the sum will be Not
  590. A Number (NaN).
  591. Examples
  592. --------
  593. >>> import numpy as np
  594. >>> np.nansum(1)
  595. 1
  596. >>> np.nansum([1])
  597. 1
  598. >>> np.nansum([1, np.nan])
  599. 1.0
  600. >>> a = np.array([[1, 1], [1, np.nan]])
  601. >>> np.nansum(a)
  602. 3.0
  603. >>> np.nansum(a, axis=0)
  604. array([2., 1.])
  605. >>> np.nansum([1, np.nan, np.inf])
  606. inf
  607. >>> np.nansum([1, np.nan, -np.inf])
  608. -inf
  609. >>> with np.errstate(invalid="ignore"):
  610. ... np.nansum([1, np.nan, np.inf, -np.inf]) # both +/- infinity present
  611. np.float64(nan)
  612. """
  613. a, mask = _replace_nan(a, 0)
  614. return np.sum(a, axis=axis, dtype=dtype, out=out, keepdims=keepdims,
  615. initial=initial, where=where)
  616. def _nanprod_dispatcher(a, axis=None, dtype=None, out=None, keepdims=None,
  617. initial=None, where=None):
  618. return (a, out)
  619. @array_function_dispatch(_nanprod_dispatcher)
  620. def nanprod(a, axis=None, dtype=None, out=None, keepdims=np._NoValue,
  621. initial=np._NoValue, where=np._NoValue):
  622. """
  623. Return the product of array elements over a given axis treating Not a
  624. Numbers (NaNs) as ones.
  625. One is returned for slices that are all-NaN or empty.
  626. Parameters
  627. ----------
  628. a : array_like
  629. Array containing numbers whose product is desired. If `a` is not an
  630. array, a conversion is attempted.
  631. axis : {int, tuple of int, None}, optional
  632. Axis or axes along which the product is computed. The default is to compute
  633. the product of the flattened array.
  634. dtype : data-type, optional
  635. The type of the returned array and of the accumulator in which the
  636. elements are summed. By default, the dtype of `a` is used. An
  637. exception is when `a` has an integer type with less precision than
  638. the platform (u)intp. In that case, the default will be either
  639. (u)int32 or (u)int64 depending on whether the platform is 32 or 64
  640. bits. For inexact inputs, dtype must be inexact.
  641. out : ndarray, optional
  642. Alternate output array in which to place the result. The default
  643. is ``None``. If provided, it must have the same shape as the
  644. expected output, but the type will be cast if necessary. See
  645. :ref:`ufuncs-output-type` for more details. The casting of NaN to integer
  646. can yield unexpected results.
  647. keepdims : bool, optional
  648. If True, the axes which are reduced are left in the result as
  649. dimensions with size one. With this option, the result will
  650. broadcast correctly against the original `arr`.
  651. initial : scalar, optional
  652. The starting value for this product. See `~numpy.ufunc.reduce`
  653. for details.
  654. .. versionadded:: 1.22.0
  655. where : array_like of bool, optional
  656. Elements to include in the product. See `~numpy.ufunc.reduce`
  657. for details.
  658. .. versionadded:: 1.22.0
  659. Returns
  660. -------
  661. nanprod : ndarray
  662. A new array holding the result is returned unless `out` is
  663. specified, in which case it is returned.
  664. See Also
  665. --------
  666. numpy.prod : Product across array propagating NaNs.
  667. isnan : Show which elements are NaN.
  668. Examples
  669. --------
  670. >>> import numpy as np
  671. >>> np.nanprod(1)
  672. 1
  673. >>> np.nanprod([1])
  674. 1
  675. >>> np.nanprod([1, np.nan])
  676. 1.0
  677. >>> a = np.array([[1, 2], [3, np.nan]])
  678. >>> np.nanprod(a)
  679. 6.0
  680. >>> np.nanprod(a, axis=0)
  681. array([3., 2.])
  682. """
  683. a, mask = _replace_nan(a, 1)
  684. return np.prod(a, axis=axis, dtype=dtype, out=out, keepdims=keepdims,
  685. initial=initial, where=where)
  686. def _nancumsum_dispatcher(a, axis=None, dtype=None, out=None):
  687. return (a, out)
  688. @array_function_dispatch(_nancumsum_dispatcher)
  689. def nancumsum(a, axis=None, dtype=None, out=None):
  690. """
  691. Return the cumulative sum of array elements over a given axis treating Not a
  692. Numbers (NaNs) as zero. The cumulative sum does not change when NaNs are
  693. encountered and leading NaNs are replaced by zeros.
  694. Zeros are returned for slices that are all-NaN or empty.
  695. Parameters
  696. ----------
  697. a : array_like
  698. Input array.
  699. axis : int, optional
  700. Axis along which the cumulative sum is computed. The default
  701. (None) is to compute the cumsum over the flattened array.
  702. dtype : dtype, optional
  703. Type of the returned array and of the accumulator in which the
  704. elements are summed. If `dtype` is not specified, it defaults
  705. to the dtype of `a`, unless `a` has an integer dtype with a
  706. precision less than that of the default platform integer. In
  707. that case, the default platform integer is used.
  708. out : ndarray, optional
  709. Alternative output array in which to place the result. It must
  710. have the same shape and buffer length as the expected output
  711. but the type will be cast if necessary. See :ref:`ufuncs-output-type` for
  712. more details.
  713. Returns
  714. -------
  715. nancumsum : ndarray.
  716. A new array holding the result is returned unless `out` is
  717. specified, in which it is returned. The result has the same
  718. size as `a`, and the same shape as `a` if `axis` is not None
  719. or `a` is a 1-d array.
  720. See Also
  721. --------
  722. numpy.cumsum : Cumulative sum across array propagating NaNs.
  723. isnan : Show which elements are NaN.
  724. Examples
  725. --------
  726. >>> import numpy as np
  727. >>> np.nancumsum(1)
  728. array([1])
  729. >>> np.nancumsum([1])
  730. array([1])
  731. >>> np.nancumsum([1, np.nan])
  732. array([1., 1.])
  733. >>> a = np.array([[1, 2], [3, np.nan]])
  734. >>> np.nancumsum(a)
  735. array([1., 3., 6., 6.])
  736. >>> np.nancumsum(a, axis=0)
  737. array([[1., 2.],
  738. [4., 2.]])
  739. >>> np.nancumsum(a, axis=1)
  740. array([[1., 3.],
  741. [3., 3.]])
  742. """
  743. a, mask = _replace_nan(a, 0)
  744. return np.cumsum(a, axis=axis, dtype=dtype, out=out)
  745. def _nancumprod_dispatcher(a, axis=None, dtype=None, out=None):
  746. return (a, out)
  747. @array_function_dispatch(_nancumprod_dispatcher)
  748. def nancumprod(a, axis=None, dtype=None, out=None):
  749. """
  750. Return the cumulative product of array elements over a given axis treating Not a
  751. Numbers (NaNs) as one. The cumulative product does not change when NaNs are
  752. encountered and leading NaNs are replaced by ones.
  753. Ones are returned for slices that are all-NaN or empty.
  754. Parameters
  755. ----------
  756. a : array_like
  757. Input array.
  758. axis : int, optional
  759. Axis along which the cumulative product is computed. By default
  760. the input is flattened.
  761. dtype : dtype, optional
  762. Type of the returned array, as well as of the accumulator in which
  763. the elements are multiplied. If *dtype* is not specified, it
  764. defaults to the dtype of `a`, unless `a` has an integer dtype with
  765. a precision less than that of the default platform integer. In
  766. that case, the default platform integer is used instead.
  767. out : ndarray, optional
  768. Alternative output array in which to place the result. It must
  769. have the same shape and buffer length as the expected output
  770. but the type of the resulting values will be cast if necessary.
  771. Returns
  772. -------
  773. nancumprod : ndarray
  774. A new array holding the result is returned unless `out` is
  775. specified, in which case it is returned.
  776. See Also
  777. --------
  778. numpy.cumprod : Cumulative product across array propagating NaNs.
  779. isnan : Show which elements are NaN.
  780. Examples
  781. --------
  782. >>> import numpy as np
  783. >>> np.nancumprod(1)
  784. array([1])
  785. >>> np.nancumprod([1])
  786. array([1])
  787. >>> np.nancumprod([1, np.nan])
  788. array([1., 1.])
  789. >>> a = np.array([[1, 2], [3, np.nan]])
  790. >>> np.nancumprod(a)
  791. array([1., 2., 6., 6.])
  792. >>> np.nancumprod(a, axis=0)
  793. array([[1., 2.],
  794. [3., 2.]])
  795. >>> np.nancumprod(a, axis=1)
  796. array([[1., 2.],
  797. [3., 3.]])
  798. """
  799. a, mask = _replace_nan(a, 1)
  800. return np.cumprod(a, axis=axis, dtype=dtype, out=out)
  801. def _nanmean_dispatcher(a, axis=None, dtype=None, out=None, keepdims=None,
  802. *, where=None):
  803. return (a, out)
  804. @array_function_dispatch(_nanmean_dispatcher)
  805. def nanmean(a, axis=None, dtype=None, out=None, keepdims=np._NoValue,
  806. *, where=np._NoValue):
  807. """
  808. Compute the arithmetic mean along the specified axis, ignoring NaNs.
  809. Returns the average of the array elements. The average is taken over
  810. the flattened array by default, otherwise over the specified axis.
  811. `float64` intermediate and return values are used for integer inputs.
  812. For all-NaN slices, NaN is returned and a `RuntimeWarning` is raised.
  813. Parameters
  814. ----------
  815. a : array_like
  816. Array containing numbers whose mean is desired. If `a` is not an
  817. array, a conversion is attempted.
  818. axis : {int, tuple of int, None}, optional
  819. Axis or axes along which the means are computed. The default is to compute
  820. the mean of the flattened array.
  821. dtype : data-type, optional
  822. Type to use in computing the mean. For integer inputs, the default
  823. is `float64`; for inexact inputs, it is the same as the input
  824. dtype.
  825. out : ndarray, optional
  826. Alternate output array in which to place the result. The default
  827. is ``None``; if provided, it must have the same shape as the
  828. expected output, but the type will be cast if necessary.
  829. See :ref:`ufuncs-output-type` for more details.
  830. keepdims : bool, optional
  831. If this is set to True, the axes which are reduced are left
  832. in the result as dimensions with size one. With this option,
  833. the result will broadcast correctly against the original `a`.
  834. If the value is anything but the default, then
  835. `keepdims` will be passed through to the `mean` or `sum` methods
  836. of sub-classes of `ndarray`. If the sub-classes methods
  837. does not implement `keepdims` any exceptions will be raised.
  838. where : array_like of bool, optional
  839. Elements to include in the mean. See `~numpy.ufunc.reduce` for details.
  840. .. versionadded:: 1.22.0
  841. Returns
  842. -------
  843. m : ndarray, see dtype parameter above
  844. If `out=None`, returns a new array containing the mean values,
  845. otherwise a reference to the output array is returned. Nan is
  846. returned for slices that contain only NaNs.
  847. See Also
  848. --------
  849. average : Weighted average
  850. mean : Arithmetic mean taken while not ignoring NaNs
  851. var, nanvar
  852. Notes
  853. -----
  854. The arithmetic mean is the sum of the non-NaN elements along the axis
  855. divided by the number of non-NaN elements.
  856. Note that for floating-point input, the mean is computed using the same
  857. precision the input has. Depending on the input data, this can cause
  858. the results to be inaccurate, especially for `float32`. Specifying a
  859. higher-precision accumulator using the `dtype` keyword can alleviate
  860. this issue.
  861. Examples
  862. --------
  863. >>> import numpy as np
  864. >>> a = np.array([[1, np.nan], [3, 4]])
  865. >>> np.nanmean(a)
  866. 2.6666666666666665
  867. >>> np.nanmean(a, axis=0)
  868. array([2., 4.])
  869. >>> np.nanmean(a, axis=1)
  870. array([1., 3.5]) # may vary
  871. """
  872. arr, mask = _replace_nan(a, 0)
  873. if mask is None:
  874. return np.mean(arr, axis=axis, dtype=dtype, out=out, keepdims=keepdims,
  875. where=where)
  876. if dtype is not None:
  877. dtype = np.dtype(dtype)
  878. if dtype is not None and not issubclass(dtype.type, np.inexact):
  879. raise TypeError("If a is inexact, then dtype must be inexact")
  880. if out is not None and not issubclass(out.dtype.type, np.inexact):
  881. raise TypeError("If a is inexact, then out must be inexact")
  882. cnt = np.sum(~mask, axis=axis, dtype=np.intp, keepdims=keepdims,
  883. where=where)
  884. tot = np.sum(arr, axis=axis, dtype=dtype, out=out, keepdims=keepdims,
  885. where=where)
  886. avg = _divide_by_count(tot, cnt, out=out)
  887. isbad = (cnt == 0)
  888. if isbad.any():
  889. warnings.warn("Mean of empty slice", RuntimeWarning, stacklevel=2)
  890. # NaN is the only possible bad value, so no further
  891. # action is needed to handle bad results.
  892. return avg
  893. def _nanmedian1d(arr1d, overwrite_input=False):
  894. """
  895. Private function for rank 1 arrays. Compute the median ignoring NaNs.
  896. See nanmedian for parameter usage
  897. """
  898. arr1d_parsed, _, overwrite_input = _remove_nan_1d(
  899. arr1d, overwrite_input=overwrite_input,
  900. )
  901. if arr1d_parsed.size == 0:
  902. # Ensure that a nan-esque scalar of the appropriate type (and unit)
  903. # is returned for `timedelta64` and `complexfloating`
  904. return arr1d[-1]
  905. return np.median(arr1d_parsed, overwrite_input=overwrite_input)
  906. def _nanmedian(a, axis=None, out=None, overwrite_input=False):
  907. """
  908. Private function that doesn't support extended axis or keepdims.
  909. These methods are extended to this function using _ureduce
  910. See nanmedian for parameter usage
  911. """
  912. if axis is None or a.ndim == 1:
  913. part = a.ravel()
  914. if out is None:
  915. return _nanmedian1d(part, overwrite_input)
  916. else:
  917. out[...] = _nanmedian1d(part, overwrite_input)
  918. return out
  919. else:
  920. # for small medians use sort + indexing which is still faster than
  921. # apply_along_axis
  922. # benchmarked with shuffled (50, 50, x) containing a few NaN
  923. if a.shape[axis] < 600:
  924. return _nanmedian_small(a, axis, out, overwrite_input)
  925. result = np.apply_along_axis(_nanmedian1d, axis, a, overwrite_input)
  926. if out is not None:
  927. out[...] = result
  928. return result
  929. def _nanmedian_small(a, axis=None, out=None, overwrite_input=False):
  930. """
  931. sort + indexing median, faster for small medians along multiple
  932. dimensions due to the high overhead of apply_along_axis
  933. see nanmedian for parameter usage
  934. """
  935. a = np.ma.masked_array(a, np.isnan(a))
  936. m = np.ma.median(a, axis=axis, overwrite_input=overwrite_input)
  937. for i in range(np.count_nonzero(m.mask.ravel())):
  938. warnings.warn("All-NaN slice encountered", RuntimeWarning,
  939. stacklevel=5)
  940. fill_value = np.timedelta64("NaT") if m.dtype.kind == "m" else np.nan
  941. if out is not None:
  942. out[...] = m.filled(fill_value)
  943. return out
  944. return m.filled(fill_value)
  945. def _nanmedian_dispatcher(
  946. a, axis=None, out=None, overwrite_input=None, keepdims=None):
  947. return (a, out)
  948. @array_function_dispatch(_nanmedian_dispatcher)
  949. def nanmedian(a, axis=None, out=None, overwrite_input=False, keepdims=np._NoValue):
  950. """
  951. Compute the median along the specified axis, while ignoring NaNs.
  952. Returns the median of the array elements.
  953. Parameters
  954. ----------
  955. a : array_like
  956. Input array or object that can be converted to an array.
  957. axis : {int, sequence of int, None}, optional
  958. Axis or axes along which the medians are computed. The default
  959. is to compute the median along a flattened version of the array.
  960. A sequence of axes is supported since version 1.9.0.
  961. out : ndarray, optional
  962. Alternative output array in which to place the result. It must
  963. have the same shape and buffer length as the expected output,
  964. but the type (of the output) will be cast if necessary.
  965. overwrite_input : bool, optional
  966. If True, then allow use of memory of input array `a` for
  967. calculations. The input array will be modified by the call to
  968. `median`. This will save memory when you do not need to preserve
  969. the contents of the input array. Treat the input as undefined,
  970. but it will probably be fully or partially sorted. Default is
  971. False. If `overwrite_input` is ``True`` and `a` is not already an
  972. `ndarray`, an error will be raised.
  973. keepdims : bool, optional
  974. If this is set to True, the axes which are reduced are left
  975. in the result as dimensions with size one. With this option,
  976. the result will broadcast correctly against the original `a`.
  977. If this is anything but the default value it will be passed
  978. through (in the special case of an empty array) to the
  979. `mean` function of the underlying array. If the array is
  980. a sub-class and `mean` does not have the kwarg `keepdims` this
  981. will raise a RuntimeError.
  982. Returns
  983. -------
  984. median : ndarray
  985. A new array holding the result. If the input contains integers
  986. or floats smaller than ``float64``, then the output data-type is
  987. ``np.float64``. Otherwise, the data-type of the output is the
  988. same as that of the input. If `out` is specified, that array is
  989. returned instead.
  990. See Also
  991. --------
  992. mean, median, percentile
  993. Notes
  994. -----
  995. Given a vector ``V`` of length ``N``, the median of ``V`` is the
  996. middle value of a sorted copy of ``V``, ``V_sorted`` - i.e.,
  997. ``V_sorted[(N-1)/2]``, when ``N`` is odd and the average of the two
  998. middle values of ``V_sorted`` when ``N`` is even.
  999. Examples
  1000. --------
  1001. >>> import numpy as np
  1002. >>> a = np.array([[10.0, 7, 4], [3, 2, 1]])
  1003. >>> a[0, 1] = np.nan
  1004. >>> a
  1005. array([[10., nan, 4.],
  1006. [ 3., 2., 1.]])
  1007. >>> np.median(a)
  1008. np.float64(nan)
  1009. >>> np.nanmedian(a)
  1010. 3.0
  1011. >>> np.nanmedian(a, axis=0)
  1012. array([6.5, 2. , 2.5])
  1013. >>> np.median(a, axis=1)
  1014. array([nan, 2.])
  1015. >>> b = a.copy()
  1016. >>> np.nanmedian(b, axis=1, overwrite_input=True)
  1017. array([7., 2.])
  1018. >>> assert not np.all(a==b)
  1019. >>> b = a.copy()
  1020. >>> np.nanmedian(b, axis=None, overwrite_input=True)
  1021. 3.0
  1022. >>> assert not np.all(a==b)
  1023. """
  1024. a = np.asanyarray(a)
  1025. # apply_along_axis in _nanmedian doesn't handle empty arrays well,
  1026. # so deal them upfront
  1027. if a.size == 0:
  1028. return np.nanmean(a, axis, out=out, keepdims=keepdims)
  1029. return fnb._ureduce(a, func=_nanmedian, keepdims=keepdims,
  1030. axis=axis, out=out,
  1031. overwrite_input=overwrite_input)
  1032. def _nanpercentile_dispatcher(
  1033. a, q, axis=None, out=None, overwrite_input=None,
  1034. method=None, keepdims=None, *, weights=None):
  1035. return (a, q, out, weights)
  1036. @array_function_dispatch(_nanpercentile_dispatcher)
  1037. def nanpercentile(
  1038. a,
  1039. q,
  1040. axis=None,
  1041. out=None,
  1042. overwrite_input=False,
  1043. method="linear",
  1044. keepdims=np._NoValue,
  1045. *,
  1046. weights=None,
  1047. ):
  1048. """
  1049. Compute the qth percentile of the data along the specified axis,
  1050. while ignoring nan values.
  1051. Returns the qth percentile(s) of the array elements.
  1052. Parameters
  1053. ----------
  1054. a : array_like
  1055. Input array or object that can be converted to an array, containing
  1056. nan values to be ignored.
  1057. q : array_like of float
  1058. Percentile or sequence of percentiles to compute, which must be
  1059. between 0 and 100 inclusive.
  1060. axis : {int, tuple of int, None}, optional
  1061. Axis or axes along which the percentiles are computed. The default
  1062. is to compute the percentile(s) along a flattened version of the
  1063. array.
  1064. out : ndarray, optional
  1065. Alternative output array in which to place the result. It must have
  1066. the same shape and buffer length as the expected output, but the
  1067. type (of the output) will be cast if necessary.
  1068. overwrite_input : bool, optional
  1069. If True, then allow the input array `a` to be modified by
  1070. intermediate calculations, to save memory. In this case, the
  1071. contents of the input `a` after this function completes is
  1072. undefined.
  1073. method : str, optional
  1074. This parameter specifies the method to use for estimating the
  1075. percentile. There are many different methods, some unique to NumPy.
  1076. See the notes for explanation. The options sorted by their R type
  1077. as summarized in the H&F paper [1]_ are:
  1078. 1. 'inverted_cdf'
  1079. 2. 'averaged_inverted_cdf'
  1080. 3. 'closest_observation'
  1081. 4. 'interpolated_inverted_cdf'
  1082. 5. 'hazen'
  1083. 6. 'weibull'
  1084. 7. 'linear' (default)
  1085. 8. 'median_unbiased'
  1086. 9. 'normal_unbiased'
  1087. The first three methods are discontinuous. NumPy further defines the
  1088. following discontinuous variations of the default 'linear' (7.) option:
  1089. * 'lower'
  1090. * 'higher',
  1091. * 'midpoint'
  1092. * 'nearest'
  1093. .. versionchanged:: 1.22.0
  1094. This argument was previously called "interpolation" and only
  1095. offered the "linear" default and last four options.
  1096. keepdims : bool, optional
  1097. If this is set to True, the axes which are reduced are left in
  1098. the result as dimensions with size one. With this option, the
  1099. result will broadcast correctly against the original array `a`.
  1100. If this is anything but the default value it will be passed
  1101. through (in the special case of an empty array) to the
  1102. `mean` function of the underlying array. If the array is
  1103. a sub-class and `mean` does not have the kwarg `keepdims` this
  1104. will raise a RuntimeError.
  1105. weights : array_like, optional
  1106. An array of weights associated with the values in `a`. Each value in
  1107. `a` contributes to the percentile according to its associated weight.
  1108. The weights array can either be 1-D (in which case its length must be
  1109. the size of `a` along the given axis) or of the same shape as `a`.
  1110. If `weights=None`, then all data in `a` are assumed to have a
  1111. weight equal to one.
  1112. Only `method="inverted_cdf"` supports weights.
  1113. .. versionadded:: 2.0.0
  1114. Returns
  1115. -------
  1116. percentile : scalar or ndarray
  1117. If `q` is a single percentile and `axis=None`, then the result
  1118. is a scalar. If multiple percentiles are given, first axis of
  1119. the result corresponds to the percentiles. The other axes are
  1120. the axes that remain after the reduction of `a`. If the input
  1121. contains integers or floats smaller than ``float64``, the output
  1122. data-type is ``float64``. Otherwise, the output data-type is the
  1123. same as that of the input. If `out` is specified, that array is
  1124. returned instead.
  1125. See Also
  1126. --------
  1127. nanmean
  1128. nanmedian : equivalent to ``nanpercentile(..., 50)``
  1129. percentile, median, mean
  1130. nanquantile : equivalent to nanpercentile, except q in range [0, 1].
  1131. Notes
  1132. -----
  1133. The behavior of `numpy.nanpercentile` with percentage `q` is that of
  1134. `numpy.quantile` with argument ``q/100`` (ignoring nan values).
  1135. For more information, please see `numpy.quantile`.
  1136. Examples
  1137. --------
  1138. >>> import numpy as np
  1139. >>> a = np.array([[10., 7., 4.], [3., 2., 1.]])
  1140. >>> a[0][1] = np.nan
  1141. >>> a
  1142. array([[10., nan, 4.],
  1143. [ 3., 2., 1.]])
  1144. >>> np.percentile(a, 50)
  1145. np.float64(nan)
  1146. >>> np.nanpercentile(a, 50)
  1147. 3.0
  1148. >>> np.nanpercentile(a, 50, axis=0)
  1149. array([6.5, 2. , 2.5])
  1150. >>> np.nanpercentile(a, 50, axis=1, keepdims=True)
  1151. array([[7.],
  1152. [2.]])
  1153. >>> m = np.nanpercentile(a, 50, axis=0)
  1154. >>> out = np.zeros_like(m)
  1155. >>> np.nanpercentile(a, 50, axis=0, out=out)
  1156. array([6.5, 2. , 2.5])
  1157. >>> m
  1158. array([6.5, 2. , 2.5])
  1159. >>> b = a.copy()
  1160. >>> np.nanpercentile(b, 50, axis=1, overwrite_input=True)
  1161. array([7., 2.])
  1162. >>> assert not np.all(a==b)
  1163. References
  1164. ----------
  1165. .. [1] R. J. Hyndman and Y. Fan,
  1166. "Sample quantiles in statistical packages,"
  1167. The American Statistician, 50(4), pp. 361-365, 1996
  1168. """
  1169. a = np.asanyarray(a)
  1170. if a.dtype.kind == "c":
  1171. raise TypeError("a must be an array of real numbers")
  1172. weak_q = type(q) in (int, float) # use weak promotion for final result type
  1173. q = np.true_divide(q, 100, out=...)
  1174. if not fnb._quantile_is_valid(q):
  1175. raise ValueError("Percentiles must be in the range [0, 100]")
  1176. if weights is not None:
  1177. if method != "inverted_cdf":
  1178. msg = ("Only method 'inverted_cdf' supports weights. "
  1179. f"Got: {method}.")
  1180. raise ValueError(msg)
  1181. if axis is not None:
  1182. axis = _nx.normalize_axis_tuple(axis, a.ndim, argname="axis")
  1183. weights = _weights_are_valid(weights=weights, a=a, axis=axis)
  1184. if np.any(weights < 0):
  1185. raise ValueError("Weights must be non-negative.")
  1186. return _nanquantile_unchecked(
  1187. a, q, axis, out, overwrite_input, method, keepdims, weights, weak_q)
  1188. def _nanquantile_dispatcher(a, q, axis=None, out=None, overwrite_input=None,
  1189. method=None, keepdims=None, *, weights=None):
  1190. return (a, q, out, weights)
  1191. @array_function_dispatch(_nanquantile_dispatcher)
  1192. def nanquantile(
  1193. a,
  1194. q,
  1195. axis=None,
  1196. out=None,
  1197. overwrite_input=False,
  1198. method="linear",
  1199. keepdims=np._NoValue,
  1200. *,
  1201. weights=None,
  1202. ):
  1203. """
  1204. Compute the qth quantile of the data along the specified axis,
  1205. while ignoring nan values.
  1206. Returns the qth quantile(s) of the array elements.
  1207. Parameters
  1208. ----------
  1209. a : array_like
  1210. Input array or object that can be converted to an array, containing
  1211. nan values to be ignored
  1212. q : array_like of float
  1213. Probability or sequence of probabilities for the quantiles to compute.
  1214. Values must be between 0 and 1 inclusive.
  1215. axis : {int, tuple of int, None}, optional
  1216. Axis or axes along which the quantiles are computed. The
  1217. default is to compute the quantile(s) along a flattened
  1218. version of the array.
  1219. out : ndarray, optional
  1220. Alternative output array in which to place the result. It must
  1221. have the same shape and buffer length as the expected output,
  1222. but the type (of the output) will be cast if necessary.
  1223. overwrite_input : bool, optional
  1224. If True, then allow the input array `a` to be modified by intermediate
  1225. calculations, to save memory. In this case, the contents of the input
  1226. `a` after this function completes is undefined.
  1227. method : str, optional
  1228. This parameter specifies the method to use for estimating the
  1229. quantile. There are many different methods, some unique to NumPy.
  1230. See the notes for explanation. The options sorted by their R type
  1231. as summarized in the H&F paper [1]_ are:
  1232. 1. 'inverted_cdf'
  1233. 2. 'averaged_inverted_cdf'
  1234. 3. 'closest_observation'
  1235. 4. 'interpolated_inverted_cdf'
  1236. 5. 'hazen'
  1237. 6. 'weibull'
  1238. 7. 'linear' (default)
  1239. 8. 'median_unbiased'
  1240. 9. 'normal_unbiased'
  1241. The first three methods are discontinuous. NumPy further defines the
  1242. following discontinuous variations of the default 'linear' (7.) option:
  1243. * 'lower'
  1244. * 'higher',
  1245. * 'midpoint'
  1246. * 'nearest'
  1247. .. versionchanged:: 1.22.0
  1248. This argument was previously called "interpolation" and only
  1249. offered the "linear" default and last four options.
  1250. keepdims : bool, optional
  1251. If this is set to True, the axes which are reduced are left in
  1252. the result as dimensions with size one. With this option, the
  1253. result will broadcast correctly against the original array `a`.
  1254. If this is anything but the default value it will be passed
  1255. through (in the special case of an empty array) to the
  1256. `mean` function of the underlying array. If the array is
  1257. a sub-class and `mean` does not have the kwarg `keepdims` this
  1258. will raise a RuntimeError.
  1259. weights : array_like, optional
  1260. An array of weights associated with the values in `a`. Each value in
  1261. `a` contributes to the quantile according to its associated weight.
  1262. The weights array can either be 1-D (in which case its length must be
  1263. the size of `a` along the given axis) or of the same shape as `a`.
  1264. If `weights=None`, then all data in `a` are assumed to have a
  1265. weight equal to one.
  1266. Only `method="inverted_cdf"` supports weights.
  1267. .. versionadded:: 2.0.0
  1268. Returns
  1269. -------
  1270. quantile : scalar or ndarray
  1271. If `q` is a single probability and `axis=None`, then the result
  1272. is a scalar. If multiple probability levels are given, first axis of
  1273. the result corresponds to the quantiles. The other axes are
  1274. the axes that remain after the reduction of `a`. If the input
  1275. contains integers or floats smaller than ``float64``, the output
  1276. data-type is ``float64``. Otherwise, the output data-type is the
  1277. same as that of the input. If `out` is specified, that array is
  1278. returned instead.
  1279. See Also
  1280. --------
  1281. quantile
  1282. nanmean, nanmedian
  1283. nanmedian : equivalent to ``nanquantile(..., 0.5)``
  1284. nanpercentile : same as nanquantile, but with q in the range [0, 100].
  1285. Notes
  1286. -----
  1287. The behavior of `numpy.nanquantile` is the same as that of
  1288. `numpy.quantile` (ignoring nan values).
  1289. For more information, please see `numpy.quantile`.
  1290. Examples
  1291. --------
  1292. >>> import numpy as np
  1293. >>> a = np.array([[10., 7., 4.], [3., 2., 1.]])
  1294. >>> a[0][1] = np.nan
  1295. >>> a
  1296. array([[10., nan, 4.],
  1297. [ 3., 2., 1.]])
  1298. >>> np.quantile(a, 0.5)
  1299. np.float64(nan)
  1300. >>> np.nanquantile(a, 0.5)
  1301. 3.0
  1302. >>> np.nanquantile(a, 0.5, axis=0)
  1303. array([6.5, 2. , 2.5])
  1304. >>> np.nanquantile(a, 0.5, axis=1, keepdims=True)
  1305. array([[7.],
  1306. [2.]])
  1307. >>> m = np.nanquantile(a, 0.5, axis=0)
  1308. >>> out = np.zeros_like(m)
  1309. >>> np.nanquantile(a, 0.5, axis=0, out=out)
  1310. array([6.5, 2. , 2.5])
  1311. >>> m
  1312. array([6.5, 2. , 2.5])
  1313. >>> b = a.copy()
  1314. >>> np.nanquantile(b, 0.5, axis=1, overwrite_input=True)
  1315. array([7., 2.])
  1316. >>> assert not np.all(a==b)
  1317. References
  1318. ----------
  1319. .. [1] R. J. Hyndman and Y. Fan,
  1320. "Sample quantiles in statistical packages,"
  1321. The American Statistician, 50(4), pp. 361-365, 1996
  1322. """
  1323. a = np.asanyarray(a)
  1324. if a.dtype.kind == "c":
  1325. raise TypeError("a must be an array of real numbers")
  1326. weak_q = type(q) in (int, float) # use weak promotion for final result type
  1327. q = np.asanyarray(q)
  1328. if not fnb._quantile_is_valid(q):
  1329. raise ValueError("Quantiles must be in the range [0, 1]")
  1330. if weights is not None:
  1331. if method != "inverted_cdf":
  1332. msg = ("Only method 'inverted_cdf' supports weights. "
  1333. f"Got: {method}.")
  1334. raise ValueError(msg)
  1335. if axis is not None:
  1336. axis = _nx.normalize_axis_tuple(axis, a.ndim, argname="axis")
  1337. weights = _weights_are_valid(weights=weights, a=a, axis=axis)
  1338. if np.any(weights < 0):
  1339. raise ValueError("Weights must be non-negative.")
  1340. return _nanquantile_unchecked(
  1341. a, q, axis, out, overwrite_input, method, keepdims, weights, weak_q)
  1342. def _nanquantile_unchecked(
  1343. a,
  1344. q,
  1345. axis=None,
  1346. out=None,
  1347. overwrite_input=False,
  1348. method="linear",
  1349. keepdims=np._NoValue,
  1350. weights=None,
  1351. weak_q=False,
  1352. ):
  1353. """Assumes that q is in [0, 1], and is an ndarray"""
  1354. # apply_along_axis in _nanpercentile doesn't handle empty arrays well,
  1355. # so deal them upfront
  1356. if a.size == 0:
  1357. return np.nanmean(a, axis, out=out, keepdims=keepdims)
  1358. return fnb._ureduce(a,
  1359. func=_nanquantile_ureduce_func,
  1360. q=q,
  1361. weights=weights,
  1362. keepdims=keepdims,
  1363. axis=axis,
  1364. out=out,
  1365. overwrite_input=overwrite_input,
  1366. method=method,
  1367. weak_q=weak_q)
  1368. def _nanquantile_ureduce_func(
  1369. a: np.array,
  1370. q: np.array,
  1371. weights: np.array,
  1372. axis: int | None = None,
  1373. out=None,
  1374. overwrite_input: bool = False,
  1375. method="linear",
  1376. weak_q=False,
  1377. ):
  1378. """
  1379. Private function that doesn't support extended axis or keepdims.
  1380. These methods are extended to this function using _ureduce
  1381. See nanpercentile for parameter usage
  1382. """
  1383. if axis is None or a.ndim == 1:
  1384. part = a.ravel()
  1385. wgt = None if weights is None else weights.ravel()
  1386. result = _nanquantile_1d(part, q, overwrite_input, method,
  1387. weights=wgt, weak_q=weak_q)
  1388. # Note that this code could try to fill in `out` right away
  1389. elif weights is None:
  1390. result = np.apply_along_axis(_nanquantile_1d, axis, a, q,
  1391. overwrite_input, method, weights, weak_q)
  1392. # apply_along_axis fills in collapsed axis with results.
  1393. # Move those axes to the beginning to match percentile's
  1394. # convention.
  1395. if q.ndim != 0:
  1396. from_ax = [axis + i for i in range(q.ndim)]
  1397. result = np.moveaxis(result, from_ax, list(range(q.ndim)))
  1398. else:
  1399. # We need to apply along axis over 2 arrays, a and weights.
  1400. # move operation axes to end for simplicity:
  1401. a = np.moveaxis(a, axis, -1)
  1402. if weights is not None:
  1403. weights = np.moveaxis(weights, axis, -1)
  1404. if out is not None:
  1405. result = out
  1406. else:
  1407. # weights are limited to `inverted_cdf` so the result dtype
  1408. # is known to be identical to that of `a` here:
  1409. result = np.empty_like(a, shape=q.shape + a.shape[:-1])
  1410. for ii in np.ndindex(a.shape[:-1]):
  1411. result[(...,) + ii] = _nanquantile_1d(
  1412. a[ii], q, weights=weights[ii],
  1413. overwrite_input=overwrite_input, method=method,
  1414. weak_q=weak_q,
  1415. )
  1416. # This path dealt with `out` already...
  1417. return result
  1418. if out is not None:
  1419. out[...] = result
  1420. return result
  1421. def _nanquantile_1d(
  1422. arr1d, q, overwrite_input=False, method="linear", weights=None,
  1423. weak_q=False,
  1424. ):
  1425. """
  1426. Private function for rank 1 arrays. Compute quantile ignoring NaNs.
  1427. See nanpercentile for parameter usage
  1428. """
  1429. # TODO: What to do when arr1d = [1, np.nan] and weights = [0, 1]?
  1430. arr1d, weights, overwrite_input = _remove_nan_1d(arr1d,
  1431. second_arr1d=weights, overwrite_input=overwrite_input)
  1432. if arr1d.size == 0:
  1433. # convert to scalar
  1434. return np.full(q.shape, np.nan, dtype=arr1d.dtype)[()]
  1435. return fnb._quantile_unchecked(
  1436. arr1d,
  1437. q,
  1438. overwrite_input=overwrite_input,
  1439. method=method,
  1440. weights=weights,
  1441. weak_q=weak_q,
  1442. )
  1443. def _nanvar_dispatcher(a, axis=None, dtype=None, out=None, ddof=None,
  1444. keepdims=None, *, where=None, mean=None,
  1445. correction=None):
  1446. return (a, out)
  1447. @array_function_dispatch(_nanvar_dispatcher)
  1448. def nanvar(a, axis=None, dtype=None, out=None, ddof=0, keepdims=np._NoValue,
  1449. *, where=np._NoValue, mean=np._NoValue, correction=np._NoValue):
  1450. """
  1451. Compute the variance along the specified axis, while ignoring NaNs.
  1452. Returns the variance of the array elements, a measure of the spread of
  1453. a distribution. The variance is computed for the flattened array by
  1454. default, otherwise over the specified axis.
  1455. For all-NaN slices or slices with zero degrees of freedom, NaN is
  1456. returned and a `RuntimeWarning` is raised.
  1457. Parameters
  1458. ----------
  1459. a : array_like
  1460. Array containing numbers whose variance is desired. If `a` is not an
  1461. array, a conversion is attempted.
  1462. axis : {int, tuple of int, None}, optional
  1463. Axis or axes along which the variance is computed. The default is to compute
  1464. the variance of the flattened array.
  1465. dtype : data-type, optional
  1466. Type to use in computing the variance. For arrays of integer type
  1467. the default is `float64`; for arrays of float types it is the same as
  1468. the array type.
  1469. out : ndarray, optional
  1470. Alternate output array in which to place the result. It must have
  1471. the same shape as the expected output, but the type is cast if
  1472. necessary.
  1473. ddof : {int, float}, optional
  1474. "Delta Degrees of Freedom": the divisor used in the calculation is
  1475. ``N - ddof``, where ``N`` represents the number of non-NaN
  1476. elements. By default `ddof` is zero.
  1477. keepdims : bool, optional
  1478. If this is set to True, the axes which are reduced are left
  1479. in the result as dimensions with size one. With this option,
  1480. the result will broadcast correctly against the original `a`.
  1481. where : array_like of bool, optional
  1482. Elements to include in the variance. See `~numpy.ufunc.reduce` for
  1483. details.
  1484. .. versionadded:: 1.22.0
  1485. mean : array_like, optional
  1486. Provide the mean to prevent its recalculation. The mean should have
  1487. a shape as if it was calculated with ``keepdims=True``.
  1488. The axis for the calculation of the mean should be the same as used in
  1489. the call to this var function.
  1490. .. versionadded:: 2.0.0
  1491. correction : {int, float}, optional
  1492. Array API compatible name for the ``ddof`` parameter. Only one of them
  1493. can be provided at the same time.
  1494. .. versionadded:: 2.0.0
  1495. Returns
  1496. -------
  1497. variance : ndarray, see dtype parameter above
  1498. If `out` is None, return a new array containing the variance,
  1499. otherwise return a reference to the output array. If ddof is >= the
  1500. number of non-NaN elements in a slice or the slice contains only
  1501. NaNs, then the result for that slice is NaN.
  1502. See Also
  1503. --------
  1504. std : Standard deviation
  1505. mean : Average
  1506. var : Variance while not ignoring NaNs
  1507. nanstd, nanmean
  1508. :ref:`ufuncs-output-type`
  1509. Notes
  1510. -----
  1511. The variance is the average of the squared deviations from the mean,
  1512. i.e., ``var = mean(abs(x - x.mean())**2)``.
  1513. The mean is normally calculated as ``x.sum() / N``, where ``N = len(x)``.
  1514. If, however, `ddof` is specified, the divisor ``N - ddof`` is used
  1515. instead. In standard statistical practice, ``ddof=1`` provides an
  1516. unbiased estimator of the variance of a hypothetical infinite
  1517. population. ``ddof=0`` provides a maximum likelihood estimate of the
  1518. variance for normally distributed variables.
  1519. Note that for complex numbers, the absolute value is taken before
  1520. squaring, so that the result is always real and nonnegative.
  1521. For floating-point input, the variance is computed using the same
  1522. precision the input has. Depending on the input data, this can cause
  1523. the results to be inaccurate, especially for `float32` (see example
  1524. below). Specifying a higher-accuracy accumulator using the ``dtype``
  1525. keyword can alleviate this issue.
  1526. For this function to work on sub-classes of ndarray, they must define
  1527. `sum` with the kwarg `keepdims`
  1528. Examples
  1529. --------
  1530. >>> import numpy as np
  1531. >>> a = np.array([[1, np.nan], [3, 4]])
  1532. >>> np.nanvar(a)
  1533. 1.5555555555555554
  1534. >>> np.nanvar(a, axis=0)
  1535. array([1., 0.])
  1536. >>> np.nanvar(a, axis=1)
  1537. array([0., 0.25]) # may vary
  1538. """
  1539. arr, mask = _replace_nan(a, 0)
  1540. if mask is None:
  1541. return np.var(arr, axis=axis, dtype=dtype, out=out, ddof=ddof,
  1542. keepdims=keepdims, where=where, mean=mean,
  1543. correction=correction)
  1544. if dtype is not None:
  1545. dtype = np.dtype(dtype)
  1546. if dtype is not None and not issubclass(dtype.type, np.inexact):
  1547. raise TypeError("If a is inexact, then dtype must be inexact")
  1548. if out is not None and not issubclass(out.dtype.type, np.inexact):
  1549. raise TypeError("If a is inexact, then out must be inexact")
  1550. if correction != np._NoValue:
  1551. if ddof != 0:
  1552. raise ValueError(
  1553. "ddof and correction can't be provided simultaneously."
  1554. )
  1555. else:
  1556. ddof = correction
  1557. # Compute mean
  1558. if type(arr) is np.matrix:
  1559. _keepdims = np._NoValue
  1560. else:
  1561. _keepdims = True
  1562. cnt = np.sum(~mask, axis=axis, dtype=np.intp, keepdims=_keepdims,
  1563. where=where)
  1564. if mean is not np._NoValue:
  1565. avg = mean
  1566. else:
  1567. # we need to special case matrix for reverse compatibility
  1568. # in order for this to work, these sums need to be called with
  1569. # keepdims=True, however matrix now raises an error in this case, but
  1570. # the reason that it drops the keepdims kwarg is to force keepdims=True
  1571. # so this used to work by serendipity.
  1572. avg = np.sum(arr, axis=axis, dtype=dtype,
  1573. keepdims=_keepdims, where=where)
  1574. avg = _divide_by_count(avg, cnt)
  1575. # Compute squared deviation from mean.
  1576. np.subtract(arr, avg, out=arr, casting='unsafe', where=where)
  1577. arr = _copyto(arr, 0, mask)
  1578. if issubclass(arr.dtype.type, np.complexfloating):
  1579. sqr = np.multiply(arr, arr.conj(), out=arr, where=where).real
  1580. else:
  1581. sqr = np.multiply(arr, arr, out=arr, where=where)
  1582. # Compute variance.
  1583. var = np.sum(sqr, axis=axis, dtype=dtype, out=out, keepdims=keepdims,
  1584. where=where)
  1585. # Precaution against reduced object arrays
  1586. try:
  1587. var_ndim = var.ndim
  1588. except AttributeError:
  1589. var_ndim = np.ndim(var)
  1590. if var_ndim < cnt.ndim:
  1591. # Subclasses of ndarray may ignore keepdims, so check here.
  1592. cnt = cnt.squeeze(axis)
  1593. dof = cnt - ddof
  1594. var = _divide_by_count(var, dof)
  1595. isbad = (dof <= 0)
  1596. if np.any(isbad):
  1597. warnings.warn("Degrees of freedom <= 0 for slice.", RuntimeWarning,
  1598. stacklevel=2)
  1599. # NaN, inf, or negative numbers are all possible bad
  1600. # values, so explicitly replace them with NaN.
  1601. var = _copyto(var, np.nan, isbad)
  1602. return var
  1603. def _nanstd_dispatcher(a, axis=None, dtype=None, out=None, ddof=None,
  1604. keepdims=None, *, where=None, mean=None,
  1605. correction=None):
  1606. return (a, out)
  1607. @array_function_dispatch(_nanstd_dispatcher)
  1608. def nanstd(a, axis=None, dtype=None, out=None, ddof=0, keepdims=np._NoValue,
  1609. *, where=np._NoValue, mean=np._NoValue, correction=np._NoValue):
  1610. """
  1611. Compute the standard deviation along the specified axis, while
  1612. ignoring NaNs.
  1613. Returns the standard deviation, a measure of the spread of a
  1614. distribution, of the non-NaN array elements. The standard deviation is
  1615. computed for the flattened array by default, otherwise over the
  1616. specified axis.
  1617. For all-NaN slices or slices with zero degrees of freedom, NaN is
  1618. returned and a `RuntimeWarning` is raised.
  1619. Parameters
  1620. ----------
  1621. a : array_like
  1622. Calculate the standard deviation of the non-NaN values.
  1623. axis : {int, tuple of int, None}, optional
  1624. Axis or axes along which the standard deviation is computed. The default is
  1625. to compute the standard deviation of the flattened array.
  1626. dtype : dtype, optional
  1627. Type to use in computing the standard deviation. For arrays of
  1628. integer type the default is float64, for arrays of float types it
  1629. is the same as the array type.
  1630. out : ndarray, optional
  1631. Alternative output array in which to place the result. It must have
  1632. the same shape as the expected output but the type (of the
  1633. calculated values) will be cast if necessary.
  1634. ddof : {int, float}, optional
  1635. Means Delta Degrees of Freedom. The divisor used in calculations
  1636. is ``N - ddof``, where ``N`` represents the number of non-NaN
  1637. elements. By default `ddof` is zero.
  1638. keepdims : bool, optional
  1639. If this is set to True, the axes which are reduced are left
  1640. in the result as dimensions with size one. With this option,
  1641. the result will broadcast correctly against the original `a`.
  1642. If this value is anything but the default it is passed through
  1643. as-is to the relevant functions of the sub-classes. If these
  1644. functions do not have a `keepdims` kwarg, a RuntimeError will
  1645. be raised.
  1646. where : array_like of bool, optional
  1647. Elements to include in the standard deviation.
  1648. See `~numpy.ufunc.reduce` for details.
  1649. .. versionadded:: 1.22.0
  1650. mean : array_like, optional
  1651. Provide the mean to prevent its recalculation. The mean should have
  1652. a shape as if it was calculated with ``keepdims=True``.
  1653. The axis for the calculation of the mean should be the same as used in
  1654. the call to this std function.
  1655. .. versionadded:: 2.0.0
  1656. correction : {int, float}, optional
  1657. Array API compatible name for the ``ddof`` parameter. Only one of them
  1658. can be provided at the same time.
  1659. .. versionadded:: 2.0.0
  1660. Returns
  1661. -------
  1662. standard_deviation : ndarray, see dtype parameter above.
  1663. If `out` is None, return a new array containing the standard
  1664. deviation, otherwise return a reference to the output array. If
  1665. ddof is >= the number of non-NaN elements in a slice or the slice
  1666. contains only NaNs, then the result for that slice is NaN.
  1667. See Also
  1668. --------
  1669. var, mean, std
  1670. nanvar, nanmean
  1671. :ref:`ufuncs-output-type`
  1672. Notes
  1673. -----
  1674. The standard deviation is the square root of the average of the squared
  1675. deviations from the mean: ``std = sqrt(mean(abs(x - x.mean())**2))``.
  1676. The average squared deviation is normally calculated as
  1677. ``x.sum() / N``, where ``N = len(x)``. If, however, `ddof` is
  1678. specified, the divisor ``N - ddof`` is used instead. In standard
  1679. statistical practice, ``ddof=1`` provides an unbiased estimator of the
  1680. variance of the infinite population. ``ddof=0`` provides a maximum
  1681. likelihood estimate of the variance for normally distributed variables.
  1682. The standard deviation computed in this function is the square root of
  1683. the estimated variance, so even with ``ddof=1``, it will not be an
  1684. unbiased estimate of the standard deviation per se.
  1685. Note that, for complex numbers, `std` takes the absolute value before
  1686. squaring, so that the result is always real and nonnegative.
  1687. For floating-point input, the *std* is computed using the same
  1688. precision the input has. Depending on the input data, this can cause
  1689. the results to be inaccurate, especially for float32 (see example
  1690. below). Specifying a higher-accuracy accumulator using the `dtype`
  1691. keyword can alleviate this issue.
  1692. Examples
  1693. --------
  1694. >>> import numpy as np
  1695. >>> a = np.array([[1, np.nan], [3, 4]])
  1696. >>> np.nanstd(a)
  1697. 1.247219128924647
  1698. >>> np.nanstd(a, axis=0)
  1699. array([1., 0.])
  1700. >>> np.nanstd(a, axis=1)
  1701. array([0., 0.5]) # may vary
  1702. """
  1703. var = nanvar(a, axis=axis, dtype=dtype, out=out, ddof=ddof,
  1704. keepdims=keepdims, where=where, mean=mean,
  1705. correction=correction)
  1706. if isinstance(var, np.ndarray):
  1707. std = np.sqrt(var, out=var)
  1708. elif hasattr(var, 'dtype'):
  1709. std = var.dtype.type(np.sqrt(var))
  1710. else:
  1711. std = np.sqrt(var)
  1712. return std