public static ndarray ediff1d(ndarray ary, ndarray to_end = null, ndarray to_begin = null) { /* * The differences between consecutive elements of an array. * * Parameters * ---------- * ary : array_like * If necessary, will be flattened before the differences are taken. * to_end : array_like, optional * Number(s) to append at the end of the returned differences. * to_begin : array_like, optional * Number(s) to prepend at the beginning of the returned differences. * * Returns * ------- * ediff1d : ndarray * The differences. Loosely, this is ``ary.flat[1:] - ary.flat[:-1]``. * * See Also * -------- * diff, gradient * * Notes * ----- * When applied to masked arrays, this function drops the mask information * if the `to_begin` and/or `to_end` parameters are used. * * Examples * -------- * >>> x = np.array([1, 2, 4, 7, 0]) * >>> np.ediff1d(x) * array([ 1, 2, 3, -7]) * * >>> np.ediff1d(x, to_begin=-99, to_end=np.array([88, 99])) * array([-99, 1, 2, 3, -7, 88, 99]) * * The returned array is always 1D. * * >>> y = [[1, 2, 4], [1, 6, 24]] * >>> np.ediff1d(y) * array([ 1, 2, -3, 5, 18]) */ // force a 1d array ary = np.asanyarray(ary).ravel(); // fast track default case if (to_begin is null && to_end is null) { return(ary.A("1:") - ary.A(":-1")); } int l_begin = 0; int l_end = 0; if (to_begin is null) { l_begin = 0; } else { to_begin = np.asanyarray(to_begin).ravel(); l_begin = len(to_begin); } if (to_end == null) { l_end = 0; } else { to_end = np.asanyarray(to_end).ravel(); l_end = len(to_end); } // do the calculation in place and copy to_begin and to_end int l_diff = Math.Max(len(ary) - 1, 0); ndarray result = np.empty(new shape(l_diff + l_begin + l_end), dtype: ary.Dtype); result = ary.__array_wrap__(result); if (l_begin > 0) { result[":" + l_begin.ToString()] = to_begin; } if (l_end > 0) { result[(l_begin + l_diff).ToString() + ":"] = to_end; } ndarray _out = result.A(l_begin.ToString() + ":" + (l_begin + l_diff).ToString()); _out = np.subtract(ary.A("1:"), ary.A(":-1")); result[l_begin.ToString() + ":" + (l_begin + l_diff).ToString()] = _out; return(result); }
private static uniqueData _unique1d(ndarray ar1, bool return_index = false, bool return_inverse = false, bool return_counts = false) { //Find the unique elements of an array, ignoring shape. var ar = np.asanyarray(ar1).flatten(); bool optional_indices = return_index || return_inverse; ndarray perm = null; ndarray aux = null; if (optional_indices) { if (return_index) { perm = ar.ArgSort(kind: NPY_SORTKIND.NPY_QUICKSORT); } else { perm = ar.ArgSort(kind: NPY_SORTKIND.NPY_MERGESORT); } aux = ar.A(perm); } else { ar = ar.Sort(); aux = ar; } ndarray mask = np.empty(aux.shape, dtype: np.Bool); mask[":1"] = true; ndarray T1 = aux.A("1:"); ndarray T2 = aux.A(":-1"); mask["1:"] = T1.NotEquals(T2); var ret = new uniqueData(); ret.data = aux.A(mask); if (return_index) { ret.indices = perm.A(mask); } if (return_inverse) { ndarray imask = np.cumsum(mask) - 1; ndarray inv_idx = np.empty(mask.shape, dtype: np.intp); inv_idx[perm] = imask; ret.inverse = inv_idx; } if (return_counts) { List <ndarray> parts = new List <ndarray>(); parts.AddRange(np.nonzero(mask)); parts.Add(np.array(new npy_intp[] { mask.size })); ndarray idx = np.concatenate(parts); ret.counts = np.diff(idx); } return(ret); }
public static ndarray in1d(ndarray ar1, ndarray ar2, bool assume_unique = false, bool invert = false) { /* * Test whether each element of a 1-D array is also present in a second array. * * Returns a boolean array the same length as `ar1` that is True * where an element of `ar1` is in `ar2` and False otherwise. * * We recommend using :func:`isin` instead of `in1d` for new code. * * Parameters * ---------- * ar1 : (M,) array_like * Input array. * ar2 : array_like * The values against which to test each value of `ar1`. * assume_unique : bool, optional * If True, the input arrays are both assumed to be unique, which * can speed up the calculation. Default is False. * invert : bool, optional * If True, the values in the returned array are inverted (that is, * False where an element of `ar1` is in `ar2` and True otherwise). * Default is False. ``np.in1d(a, b, invert=True)`` is equivalent * to (but is faster than) ``np.invert(in1d(a, b))``. * * .. versionadded:: 1.8.0 * * Returns * ------- * in1d : (M,) ndarray, bool * The values `ar1[in1d]` are in `ar2`. * * See Also * -------- * isin : Version of this function that preserves the * shape of ar1. * numpy.lib.arraysetops : Module with a number of other functions for * performing set operations on arrays. * * Notes * ----- * `in1d` can be considered as an element-wise function version of the * python keyword `in`, for 1-D sequences. ``in1d(a, b)`` is roughly * equivalent to ``np.array([item in b for item in a])``. * However, this idea fails if `ar2` is a set, or similar (non-sequence) * container: As ``ar2`` is converted to an array, in those cases * ``asarray(ar2)`` is an object array rather than the expected array of * contained values. * * .. versionadded:: 1.4.0 * * Examples * -------- * >>> test = np.array([0, 1, 2, 5, 0]) * >>> states = [0, 2] * >>> mask = np.in1d(test, states) * >>> mask * array([ True, False, True, False, True]) * >>> test[mask] * array([0, 2, 0]) * >>> mask = np.in1d(test, states, invert=True) * >>> mask * array([False, True, False, True, False]) * >>> test[mask] * array([1, 5]) */ // Ravel both arrays, behavior for the first array could be different ar1 = np.asarray(ar1).ravel(); ar2 = np.asarray(ar2).ravel(); //Check if one of the arrays may contain arbitrary objects bool contains_object = ar1.Dtype.hasobject || ar2.Dtype.hasobject; // This code is run when // a) the first condition is true, making the code significantly faster // b) the second condition is true (i.e. `ar1` or `ar2` may contain // arbitrary objects), since then sorting is not guaranteed to work if (len(ar2) < 10 * Math.Pow(len(ar1), 0.145) || contains_object) { ndarray mask; if (invert) { mask = np.ones(new shape(len(ar1)), dtype: np.Bool); foreach (dynamic a in ar2) { ndarray temp = ar1 != a; mask &= temp; } } else { mask = np.zeros(new shape(len(ar1)), dtype: np.Bool); foreach (dynamic a in ar2) { ndarray temp = ar1 == a; mask |= temp; } } return(mask); } // Otherwise use sorting ndarray rev_idx = null; if (!assume_unique) { var temp = np.unique(ar1, return_inverse: true); ar1 = temp.data; rev_idx = temp.indices; ar2 = np.unique(ar2).data; } ndarray ar = np.concatenate(ar1, ar2); // We need this to be a stable sort, so always use 'mergesort' // here. The values from the first array should always come before // the values from the second array. ndarray order = ar.ArgSort(kind: NPY_SORTKIND.NPY_MERGESORT); ndarray bool_ar; ndarray sar = ar.A(order); if (invert) { bool_ar = (sar.A("1:")).NotEquals(sar.A(":-1")); } else { bool_ar = (sar.A("1:")).Equals(sar.A(":-1")); } ndarray flag = np.concatenate(new ndarray[] { bool_ar, np.array(new bool[] { invert }) }); ndarray ret = np.empty(ar.shape, dtype: np.Bool); ret[order] = flag; if (assume_unique) { return(ret.A(":" + len(ar1).ToString())); } else { return(ret.A(rev_idx)); } }
/// <summary> /// Return a 2-D array with ones on the diagonal and zeros elsewhere /// </summary> /// <param name="N">Number of rows in the output</param> /// <param name="M">(optional) Number of columns in the output. If None, defaults to N</param> /// <param name="k">(optional) Index of the diagonal: 0 (the default) refers to the main diagonal, a positive value refers to an upper diagonal, and a negative value to a lower diagonal.</param> /// <param name="dtype">(optional) Data-type of the returned array</param> /// <param name="order">(optional)</param> /// <returns>An array where all elements are equal to zero, except for the k-th diagonal, whose values are equal to one</returns> public static ndarray eye(int N, int?M = null, int k = 0, dtype dtype = null, NPY_ORDER order = NPY_ORDER.NPY_CORDER) { /* * Return a 2-D array with ones on the diagonal and zeros elsewhere. * * Parameters * ---------- * N : int * Number of rows in the output. * M : int, optional * Number of columns in the output. If None, defaults to `N`. * k : int, optional * Index of the diagonal: 0 (the default) refers to the main diagonal, * a positive value refers to an upper diagonal, and a negative value * to a lower diagonal. * dtype : data-type, optional * Data-type of the returned array. * order : {'C', 'F'}, optional * Whether the output should be stored in row-major (C-style) or * column-major (Fortran-style) order in memory. * * .. versionadded:: 1.14.0 * * Returns * ------- * I : ndarray of shape (N,M) * An array where all elements are equal to zero, except for the `k`-th * diagonal, whose values are equal to one. * * See Also * -------- * identity : (almost) equivalent function * diag : diagonal 2-D array from a 1-D array specified by the user. * * Examples * -------- * >>> np.eye(2, dtype=int) * array([[1, 0], * [0, 1]]) * >>> np.eye(3, k=1) * array([[ 0., 1., 0.], * [ 0., 0., 1.], * [ 0., 0., 0.]]) * */ int i; if (M == null) { M = N; } ndarray m = zeros(new shape(N, (int)M), dtype: dtype, order: order); if (k >= M) { return(m); } if (k >= 0) { i = k; } else { i = (-k) * (int)M; } m.A(":" + (M - k).ToString()).Flat[i.ToString() + "::" + (M + 1).ToString()] = 1; return(m); }