_nanfunctions_impl.py 70 KB

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