def test_nans_6(self): "afunc.nans_6" shape = 0 dtype = str actual = nans(shape, dtype) desired = np.zeros(shape, dtype=dtype) assert_equal(actual, desired)
def test_nans_4(self): "afunc.nans_4" shape = (2,) dtype = object actual = nans(shape, dtype) desired = np.array([None, None]) assert_equal(actual, desired)
def test_nans_2(self): "afunc.nans_2" shape = (2,) dtype = float actual = nans(shape, dtype) desired = np.array([nan, nan]) assert_almost_equal(actual, desired)
def test_nans_3(self): "afunc.nans_3" shape = (2,) dtype = str actual = nans(shape, dtype) desired = np.array(['', '']) assert_equal(actual, desired)
def test_nans_5(self): "afunc.nans_5" shape = (2, 4, 3) dtype = object actual = nans(shape, dtype) desired = np.zeros(shape, dtype=dtype) desired[:] = None assert_equal(actual, desired)
def move_func_strides(func, arr, window, axis=-1, **kwargs): "Generic moving window function implemented with strides." if axis == None: raise ValueError, "An `axis` value of None is not supported." if window < 1: raise ValueError, "`window` must be at least 1." if window > arr.shape[axis]: raise ValueError, "`window` is too long." ndim = arr.ndim as_strided = np.lib.stride_tricks.as_strided idx = range(ndim) axis = idx[axis] arrshape0 = tuple(arr.shape) if axis >= ndim: raise IndexError, "`axis` is out of range." if ndim == 1: strides = arr.strides shape = (arr.size - window + 1, window) strides = 2 * strides z = as_strided(arr, shape=shape, strides=strides) y = func(z, axis=1, **kwargs) elif ndim == 2: if axis == 1: arr = arr.T strides = arr.strides shape = (arr.shape[0] - window + 1, window, arr.shape[1]) strides = (strides[0],) + strides z = as_strided(arr, shape=shape, strides=strides) y = func(z, axis=1, **kwargs) if axis == 1: y = y.T elif ndim == 3: if axis > 0: arr = arr.swapaxes(0, axis) strides = arr.strides shape = (arr.shape[0]-window+1, window, arr.shape[1], arr.shape[2]) strides = (strides[0],) + strides z = as_strided(arr, shape=shape, strides=strides) y = func(z, axis=1, **kwargs) if axis > 0: y = y.swapaxes(0, axis) else: raise ValueError, "Only 1d, 2d, and 3d input arrays are supported." ynan = nans(arrshape0) index = [slice(None)] * ndim index[axis] = slice(window - 1, None) ynan[index] = y return ynan
def move_func_strides(func, arr, window, axis=-1, **kwargs): "Generic moving window function implemented with strides." if axis is None: raise ValueError("An `axis` value of None is not supported.") if window < 1: raise ValueError("`window` must be at least 1.") if window > arr.shape[axis]: raise ValueError("`window` is too long.") ndim = arr.ndim as_strided = np.lib.stride_tricks.as_strided idx = range(ndim) axis = idx[axis] arrshape0 = tuple(arr.shape) if axis >= ndim: raise IndexError("`axis` is out of range.") if ndim == 1: strides = arr.strides shape = (arr.size - window + 1, window) strides = 2 * strides z = as_strided(arr, shape=shape, strides=strides) y = func(z, axis=1, **kwargs) elif ndim == 2: if axis == 1: arr = arr.T strides = arr.strides shape = (arr.shape[0] - window + 1, window, arr.shape[1]) strides = (strides[0], ) + strides z = as_strided(arr, shape=shape, strides=strides) y = func(z, axis=1, **kwargs) if axis == 1: y = y.T elif ndim == 3: if axis > 0: arr = arr.swapaxes(0, axis) strides = arr.strides shape = (arr.shape[0] - window + 1, window, arr.shape[1], arr.shape[2]) strides = (strides[0], ) + strides z = as_strided(arr, shape=shape, strides=strides) y = func(z, axis=1, **kwargs) if axis > 0: y = y.swapaxes(0, axis) else: raise ValueError("Only 1d, 2d, and 3d input arrays are supported.") ynan = nans(arrshape0) index = [slice(None)] * ndim index[axis] = slice(window - 1, None) ynan[index] = y return ynan
def move_func_loop(func, arr, window, axis=-1, **kwargs): "Generic moving window function implemented with a python loop." if axis == None: raise ValueError, "An `axis` value of None is not supported." if window < 1: raise ValueError, "`window` must be at least 1." if window > arr.shape[axis]: raise ValueError, "`window` is too long." y = nans(arr.shape) idx1 = [slice(None)] * arr.ndim idx2 = list(idx1) for i in range(window - 1, arr.shape[axis]): idx1[axis] = slice(i + 1 - window, i + 1) idx2[axis] = i y[idx2] = func(arr[idx1], axis=axis, **kwargs) return y
def move_func_loop(func, arr, window, axis=-1, **kwargs): "Generic moving window function implemented with a python loop." if axis is None: raise ValueError("An `axis` value of None is not supported.") if window < 1: raise ValueError("`window` must be at least 1.") if window > arr.shape[axis]: raise ValueError("`window` is too long.") y = nans(arr.shape) idx1 = [slice(None)] * arr.ndim idx2 = list(idx1) for i in range(window - 1, arr.shape[axis]): idx1[axis] = slice(i + 1 - window, i + 1) idx2[axis] = i y[idx2] = func(arr[idx1], axis=axis, **kwargs) return y
def test_nans_1(self): "afunc.nans_1" shape = (2,) actual = nans(shape) desired = np.array([nan, nan]) assert_almost_equal(actual, desired)
def lastrank(x, axis=-1, decay=0.0): """ The ranking of the last element along the axis, ignoring NaNs. The ranking is normalized to be between -1 and 1 instead of the more common 1 and N. The results are adjusted for ties. Suitably slicing the output of the `ranking` method will give the same result as `lastrank`. The only difference is that `lastrank` is faster. Parameters ---------- x : numpy array The array to rank. axis : int, optional The axis over which to rank. By default (axis=-1) the ranking (and reducing) is performed over the last axis. decay : scalar, optional Exponential decay strength. Cannot be negative. The default (decay=0) is no decay. In normal ranking (decay=0) all elements used to calculate the rank are equally weighted and so the ordering of all but the last element does not matter. In exponentially decayed ranking the ordering of the elements influences the ranking: elements nearer the last element get more weight. Returns ------- d : array In the case of, for example, a 2d array of shape (n, m) and axis=1, the output will contain the rank (normalized to be between -1 and 1 and adjusted for ties) of the the last element of each row. The output in this example will have shape (n,). Examples -------- Create an array: >>> y1 = larry([1, 2, 3]) What is the rank of the last element (the value 3 in this example)? It is the largest element so the rank is 1.0: >>> import numpy as np >>> from la.afunc import lastrank >>> x1 = np.array([1, 2, 3]) >>> lastrank(x1) 1.0 Now let's try an example where the last element has the smallest value: >>> x2 = np.array([3, 2, 1]) >>> lastrank(x2) -1.0 Here's an example where the last element is not the minimum or maximum value: >>> x3 = np.array([1, 3, 4, 5, 2]) >>> lastrank(x3) -0.5 Finally, let's add a large decay. The decay means that the elements closest to the last element receive the most weight. Because the decay is large, the first element (the value 1) doesn't get any weight and therefore the last element (2) becomes the smallest element: >>> lastrank(x3, decay=10) -1.0 """ if x.size == 0: # At least one dimension has length 0 shape = list(x.shape) shape.pop(axis) r = nans(shape, dtype=x.dtype) if (r.ndim == 0) and (r.size == 1): r = np.nan return r indlast = [slice(None)] * x.ndim indlast[axis] = slice(-1, None) indlast2 = [slice(None)] * x.ndim indlast2[axis] = -1 if decay > 0: # Exponential decay nt = x.shape[axis] w = nt - np.ones(nt).cumsum() w = np.exp(-decay * w) w = nt * w / w.sum() matchdim = [None] * x.ndim matchdim[axis] = slice(None) w = w[matchdim] g = ((x[indlast] > x) * w).sum(axis) e = ((x[indlast] == x) * w).sum(axis) n = (np.isfinite(x) * w).sum(axis) r = (g + g + e - w.flat[-1]) / 2.0 r = r / (n - w.flat[-1]) elif decay < 0: raise ValueError('decay must be greater than or equal to zero.') else: # Special case the most common case, decay = 0, for speed g = (x[indlast] > x).sum(axis) e = (x[indlast] == x).sum(axis) n = np.isfinite(x).sum(axis) r = (g + g + e - 1.0) / 2.0 r = r / (n - 1.0) r = 2.0 * (r - 0.5) if x.ndim == 1: if not np.isfinite(x[indlast2]): r = np.nan else: np.putmask(r, ~np.isfinite(x[indlast2]), np.nan) return r