Source code for pyjams.closest

#!/usr/bin/env python
"""
Index in array which entry is closest to a given number.

This module was written by Matthias Cuntz while at Department of Computational
Hydrosystems, Helmholtz Centre for Environmental Research - UFZ, Leipzig,
Germany, and continued while at Institut National de Recherche pour
l'Agriculture, l'Alimentation et l'Environnement (INRAE), Nancy, France.

:copyright: Copyright 2012-2023 Matthias Cuntz, see AUTHORS.rst for details.
:license: MIT License, see LICENSE for details.

.. moduleauthor:: Matthias Cuntz

The following functions are provided:

.. autosummary::
   closest

History
    * Written Jan 2012 by Matthias Cuntz (mc (at) macu (dot) de)
    * Ported to Python 3, Feb 2013, Matthias Cuntz
    * Make numpy docstring format, Apr 2020, Matthias Cuntz
    * Ported into pyjams, Oct 2021, Matthias Cuntz
    * More consistent docstrings, Jan 2022, Matthias Cuntz
    * Support pandas Series and DataFrame, Jun 2023, Matthias Cuntz

"""
import numpy as np
from .helper import input2array


__all__ = ['closest']


[docs]def closest(arr, num, value=False): """ Index in array which entry is closest to a given number. Closest returns the index of an array (arr) at which the entry is closest to a given number (num), which is `argmin(abs(arr-num))`. Parameters ---------- arr : array_like Array to search closest entry num : number Number to which the closest entry is searched for in arr value : bool, optional Returns closest array element instead of index if True (default: False) Returns ------- index : int Index of element closest to given number in flattend array. Use np.unravel_index to get index tuple. Examples -------- >>> arr = np.arange(100)/99.*5. >>> print(closest(arr, 3.125)) 62 >>> out = closest(arr, 3.125, value=True) >>> print('{:.3f}'.format(out)) 3.131 >>> arr = np.arange(100).reshape((10,10))/99.*5. >>> out = closest(arr, 3.125, value=True) >>> print('{:.3f}'.format(out)) 3.131 >>> print(closest(arr, 3.125)) 62 >>> ii = np.unravel_index(closest(arr, 3.125), arr.shape) >>> print(ii) (6, 2) >>> out = arr[ii] >>> print('{:.3f}'.format(out)) 3.131 """ marr = input2array(arr) out = np.argmin(np.abs(marr - num)) if value: return marr.flat[out] else: return out
if __name__ == '__main__': import doctest doctest.testmod(optionflags=doctest.NORMALIZE_WHITESPACE)