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(); // 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)) { ndarray mask; if (invert) { mask = np.ones(new shape(len(ar1)), dtype: np.Bool); foreach (dynamic a in ar2) { if (ar1.TypeNum == NPY_TYPES.NPY_STRING) { string aa = a.ToString(); ndarray temp = ar1.NotEquals(aa); mask &= temp; } else { ndarray temp = ar1 != a; mask &= temp; } } } else { mask = np.zeros(new shape(len(ar1)), dtype: np.Bool); foreach (dynamic a in ar2) { if (ar1.TypeNum == NPY_TYPES.NPY_STRING) { string aa = a.ToString(); ndarray temp = ar1.Equals(aa); mask |= temp; } else { 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, return_index: 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)); } }
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); }