def max_f(a, axis=None, masked=False): """Return the maximum of an array or maximum along a specified axis. :Parameters: a: numpy array_like Input array axis: `int`, optional Axis along which to operate. By default, flattened input is used. masked: `bool` :Returns: 2-`tuple` of `numpy.ndarray` The sample size and the maximum. """ (N,) = sample_size_f(a, axis=axis, masked=masked) amax = numpy_amax(a, axis=axis) if not numpy_ndim(amax): # Make sure that we have a numpy array (as opposed to, e.g. a # numpy.float64) amax = numpy_asanyarray(amax) return asanyarray(N, amax)
def sw_f(a, axis=None, masked=False, weights=None, N=None, sum_of_squares=False): '''TODO ''' if N is None: N, = sample_size_f(a, axis=axis, masked=masked) if weights is not None: # A weights array has been provided weights = double_precision(weights) if weights.ndim < a.ndim: weights = broadcast_array(weights, a.shape) if masked: weights = numpy_ma_array(weights, mask=a.mask, copy=False) if sum_of_squares: weights = weights * weights sw = weights.sum(axis=axis) if not numpy_ndim(sw): sw = numpy_asanyarray(sw) else: # The sum of weights is equal to the sample size (i.e. an # unweighted sample) sw = N.copy() return asanyarray(N, sw)
def max_f(a, axis=None, masked=False): '''Return the maximum of an array, or the maxima of an array along an axis. :Parameters: a: numpy array_like Input array axis: `int`, optional Axis along which to operate. By default, flattened input is used. masked: `bool` :Returns: out: 2-tuple of numpy arrays The sample sizes and the maxima. ''' N, = sample_size_f(a, axis=axis, masked=masked) amax = numpy_amax(a, axis=axis) if not numpy_ndim(amax): # Make sure that we have a numpy array (as opposed to, e.g. a # numpy.float64) amax = numpy_asanyarray(amax) return asanyarray(N, amax)
def mid_range_f(a, axis=None, masked=False): """Return the minimum and maximum of an array or the minimum and maximum along an axis. ``mid_range_f(a, axis=axis)`` is equivalent to ``(numpy.amin(a, axis=axis), numpy.amax(a, axis=axis))`` :Parameters: a: numpy array_like Input array axis: `int`, optional Axis along which to operate. By default, flattened input is used. kwargs: ignored :Returns: 3-`tuple` The sample size, minimum and maximum inside a 3-tuple. """ (N,) = sample_size_f(a, axis=axis, masked=masked) amin = numpy_amin(a, axis=axis) amax = numpy_amax(a, axis=axis) if not numpy_ndim(amin): # Make sure that we have a numpy array (as opposed to, e.g. a # numpy.float64) amin = numpy_asanyarray(amin) amax = numpy_asanyarray(amax) return asanyarray(N, amin, amax)
def st2rt(array, units_in, units_out, dummy1=None): '''The returned array is always independent. :Parameters: array: numpy array-like of ISO 8601 date-time strings units_in: `Units` or `None` units_out: `Units` dummy1: Ignored. :Returns: `numpy.ndarray` An array of floats with the same shape as *array*. ''' array = st2dt(array, units_in) ndim = numpy_ndim(array) if not ndim and isinstance(array, numpy_ndarray): # This necessary because date2num gets upset if you pass # it a scalar numpy array array = array.item() array = units_out._utime.date2num(array) if not ndim: array = numpy_array(array) return array
def sample_size_f(a, axis=None, masked=False): """Return the sample size. :Parameters: axis: `int`, optional Axis along which to operate. By default, flattened input is used. :Returns: `numpy.ndarray` """ if masked: N = numpy_sum(~a.mask, axis=axis, dtype=float) if not numpy_ndim(N): N = numpy_asanyarray(N) else: if axis is None: N = numpy_array(a.size, dtype=float) else: shape = a.shape N = numpy_empty(shape[:axis] + shape[axis + 1 :], dtype=float) N[...] = shape[axis] # --- End: if return asanyarray(N)
def sw_f(a, axis=None, masked=False, weights=None, N=None, sum_of_squares=False): """Return the sum of weights for an array. :Parameters: a: numpy array_like Input array axis: `int`, optional Axis along which to operate. By default, flattened input is used. masked: `bool`, optional weights: numpy array-like, optional Weights associated with values of the array. By default the statistics are unweighted. N: `numpy.ndarray` Sample size sum_of_squares: delta degrees of freedom :Returns: 2-`tuple` of `numpy.ndarray` The sample size and the sum of weights. """ if N is None: (N, ) = sample_size_f(a, axis=axis, masked=masked) if weights is not None: # A weights array has been provided weights = double_precision(weights) if weights.ndim < a.ndim: weights = broadcast_array(weights, a.shape) if masked: weights = numpy_ma_array(weights, mask=a.mask, copy=False) if sum_of_squares: weights = weights * weights sw = weights.sum(axis=axis) if not numpy_ndim(sw): sw = numpy_asanyarray(sw) else: # The sum of weights is equal to the sample size (i.e. an # unweighted sample) sw = N.copy() return asanyarray(N, sw)
def rt2dt(array, units_in, units_out=None, dummy1=None): '''Convert reference times to date-time objects The returned array is always independent. :Parameters: array: numpy array-like units_in: `Units` units_out: *optional* Ignored. dummy1: Ignored. :Returns: `numpy.ndarray` An array of `cf.Datetime` objects with the same shape as *array*. ''' mask = None if numpy_ma_isMA(array): # num2date has issues if the mask is nomask mask = array.mask if mask is numpy_ma_nomask or not numpy_ma_is_masked(array): array = array.view(numpy_ndarray) units = units_in.units calendar = getattr(units_in, 'calendar', 'standard') array = cftime.num2date(array, units, calendar, only_use_cftime_datetimes=True) # array = units_in._utime.num2date(array) if mask is not None: array = numpy_ma_masked_where(mask, array) ndim = numpy_ndim(array) if mask is None: # There is no missing data return numpy_array(array, dtype=object) # return numpy_vectorize( # partial(dt2Dt, calendar=units_in._calendar), # otypes=[object])(array) else: # There is missing data if not ndim: return numpy_ma_masked_all((), dtype=object) else: # array = numpy_array(array) # array = numpy_vectorize( # partial(dt2Dt, calendar=units_in._calendar), # otypes=[object])(array) return numpy_ma_masked_where(mask, array)
def pmin(x, y): '''TODO :Parameters: x: `numpy.ndarray` May be updated in place and should not be used again. y: `numpy.ndarray` Will not be updated in place. :Returns: out: `numpy.ndarray` ''' if numpy_ma_isMA(x): if numpy_ma_isMA(y): # x and y are both masked z = numpy_minimum(x, y) z = numpy_ma_where(x.mask & ~y.mask, y, z) x = numpy_ma_where(y.mask & ~x.mask, x, z) if x.mask is numpy_ma_nomask: x = numpy_array(x) else: # Only x is masked z = numpy_minimum(x, y) x = numpy_ma_where(x.mask, y, z) if x.mask is numpy_ma_nomask: x = numpy_array(x) elif numpy_ma_isMA(y): # Only y is masked z = numpy_minimum(x, y) x = numpy_ma_where(y.mask, x, z) if x.mask is numpy_ma_nomask: x = numpy_array(x) else: # x and y are both unmasked if not numpy_ndim(x): # Make sure that we have a numpy array (as opposed to, # e.g. a numpy.float64) x = numpy_asanyarray(x) numpy_minimum(x, y, out=x) return x
def pmax(x, y): """The element-wise maximum of two arrays. :Parameters: x: array-like May be updated in place and should not be used again. y: array-like Will not be updated in place. :Returns: `numpy.ndarray` """ if numpy_ma_isMA(x): if numpy_ma_isMA(y): # x and y are both masked z = numpy_maximum(x, y) z = numpy_ma_where(x.mask & ~y.mask, y, z) x = numpy_ma_where(y.mask & ~x.mask, x, z) if x.mask is numpy_ma_nomask: # not numpy_any(x.mask): x = numpy_array(x) else: # Only x is masked z = numpy_maximum(x, y) x = numpy_ma_where(x.mask, y, z) if x.mask is numpy_ma_nomask: # not numpy_any(x.mask): x = numpy_array(x) elif numpy_ma_isMA(y): # Only y is masked z = numpy_maximum(x, y) x = numpy_ma_where(y.mask, x, z) if x.mask is numpy_ma_nomask: # not numpy_any(x.mask): x = numpy_array(x) else: # x and y are both unmasked if not numpy_ndim(x): # Make sure that we have a numpy array (as opposed to, # e.g. a numpy.float64) x = numpy_asanyarray(x) numpy_maximum(x, y, out=x) return x
def sum_f(a, axis=None, weights=None, masked=False): """Return the sum of an array or the sum along an axis. ``sum_f(a, axis=axis)`` is equivalent to ``(numpy.sum(a, axis=axis),)`` :Parameters: a: numpy array-like Input array weights: numpy array-like, optional Weights associated with values of the array. By default the statistics are unweighted. axis: `int`, optional Axis along which to operate. By default, flattened input is used. :Returns: 2-`tuple` of `numpy.ndarray` The sample size and the sum. """ a = double_precision(a) (N,) = sample_size_f(a, axis=axis, masked=masked) if weights is not None: # A weights array has been provided weights = double_precision(weights) if weights.ndim < a.ndim: weights = broadcast_array(weights, a.shape) a = a * weights asum = a.sum(axis=axis) if not numpy_ndim(asum): asum = numpy_asanyarray(asum) return asanyarray(N, asum)
def sum_f(a, axis=None, weights=None, masked=False): '''Return the sum of an array or the sum along an axis. ``sum_f(a, axis=axis)`` is equivalent to ``(numpy.sum(a, axis=axis),)`` :Parameters: a: numpy array-like Input array weights: numpy array-like, optional TODO axis: `int`, optional Axis along which to operate. By default, flattened input is used. :Returns: `tuple` 2-tuple ''' a = double_precision(a) N, = sample_size_f(a, axis=axis, masked=masked) if weights is not None: # A weights array has been provided weights = double_precision(weights) if weights.ndim < a.ndim: weights = broadcast_array(weights, a.shape) a = a * weights asum = a.sum(axis=axis) if not numpy_ndim(asum): asum = numpy_asanyarray(asum) return asanyarray(N, asum)
def mean_f(a, axis=None, weights=None, masked=False): """The weighted average along the specified axes. :Parameters: a: array-like Input array. Not all missing data axis: `int`, optional Axis along which to operate. By default, flattened input is used. weights: numpy array-like, optional Weights associated with values of the array. By default the statistics are unweighted. masked: `bool`, optional :Returns: 3-`tuple` of `numpy.ndarray` The sample size, average and sum of weights inside a 3-tuple. """ a = double_precision(a) if masked: average = numpy_ma_average else: average = numpy_average avg, sw = average(a, axis=axis, weights=weights, returned=True) if not numpy_ndim(avg): avg = numpy_asanyarray(avg) sw = numpy_asanyarray(sw) if weights is None: N = sw.copy() else: (N,) = sample_size_f(a, axis=axis, masked=masked) return asanyarray(N, avg, sw)
def mean_f(a, axis=None, weights=None, masked=False): '''The weighted average along the specified axes. :Parameters: a: array-like Input array. Not all missing data axis: `int`, optional Axis along which to operate. By default, flattened input is used. weights: array-like, optional masked: `bool`, optional :Returns: out: `tuple` 3-tuple. ''' a = double_precision(a) if masked: average = numpy_ma_average else: average = numpy_average avg, sw = average(a, axis=axis, weights=weights, returned=True) if not numpy_ndim(avg): avg = numpy_asanyarray(avg) sw = numpy_asanyarray(sw) if weights is None: N = sw.copy() else: N, = sample_size_f(a, axis=axis, masked=masked) return asanyarray(N, avg, sw)
def asanyarray(*args): '''TODO :Parameters: args: sequence of `numpy.ndarray` :Returns: out: `tuple` ''' out = [] for x in args: if x is not None and not numpy_ndim(x): # Make sure that we have a numpy array (as opposed to, e.g. a # numpy.float64) out.append(numpy_asanyarray(x)) else: out.append(x) # --- End: for return out
def asanyarray(*args): """Return every input array as an numpy ndarray, or a subclass of. :Parameters: args: sequence of array-like input objects :Returns: `tuple` The input objects left as, else converted to, `numpy.ndarray` """ out = [] for x in args: if x is not None and not numpy_ndim(x): # Make sure that we have a numpy array (as opposed to, e.g. a # numpy.float64) out.append(numpy_asanyarray(x)) else: out.append(x) # --- End: for return out
def sample_size_f(a, axis=None, masked=False): '''TODO :Parameters: axis: `int`, optional non-negative ''' if masked: N = numpy_sum(~a.mask, axis=axis, dtype=float) if not numpy_ndim(N): N = numpy_asanyarray(N) else: if axis is None: N = numpy_array(a.size, dtype=float) else: shape = a.shape N = numpy_empty(shape[:axis] + shape[axis + 1:], dtype=float) N[...] = shape[axis] # --- End: if return asanyarray(N)
def dt2rt(array, units_in, units_out, dummy1=None): '''Round to the nearest millisecond. This is only necessary whilst netCDF4 time functions have an accuracy of no better than 1 millisecond (which is still the case at version 1.2.2). The returned array is always independent. :Parameters: array: numpy array-like of date-time objects units_in: Ignored. units_out: `Units` dummy1: Ignored. :Returns: `numpy.ndarray` An array of numbers with the same shape as *array*. ''' ndim = numpy_ndim(array) if not ndim and isinstance(array, numpy_ndarray): # This necessary because date2num gets upset if you pass # it a scalar numpy array array = array.item() # calendar = getattr(units_out, 'calendar', '') # if calendar # array = cftime.date2num( # array, units=units_out.units, # calendar=getattr(units_out, 'calendar', 'standard') # ) array = units_out._utime.date2num(array) if not ndim: array = numpy_array(array) # Round to the nearest millisecond. This is only necessary whilst # netCDF4 time functions have an accuracy of no better than 1 # millisecond (which is still the case at version 1.2.2). units = units_out._utime.units decimals = 3 month = False year = False day = units in cftime.day_units if day: array *= 86400.0 else: sec = units in cftime.sec_units if not sec: hr = units in cftime.hr_units if hr: array *= 3600.0 else: m = units in cftime.min_units if m: array *= 60.0 else: millisec = units in cftime.millisec_units if millisec: decimals = 0 else: microsec = units in cftime.microsec_units if microsec: decimals = -3 else: month = units in ('month', 'months') if month: array *= (365.242198781 / 12.0) * 86400.0 else: year = units in ('year', 'years', 'yr') if year: array *= 365.242198781 * 86400.0 # --- End: if array = numpy_around(array, decimals, array) if day: array /= 86400.0 elif sec: pass elif hr: array /= 3600.0 elif m: array /= 60.0 elif month: array /= (365.242198781 / 12.0) * 86400.0 elif year: array /= 365.242198781 * 86400.0 if not ndim: array = numpy_asanyarray(array) return array