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)); } }