Beispiel #1
0
        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);
        }
Beispiel #2
0
        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);
        }
Beispiel #3
0
        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));
            }
        }
Beispiel #4
0
        /// <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);
        }