summaryrefslogtreecommitdiff
path: root/numpy
diff options
context:
space:
mode:
Diffstat (limited to 'numpy')
-rw-r--r--numpy/lib/arraysetops.py33
-rw-r--r--numpy/lib/tests/test_arraysetops.py9
-rw-r--r--numpy/ma/extras.py9
-rw-r--r--numpy/ma/tests/test_extras.py13
4 files changed, 54 insertions, 10 deletions
diff --git a/numpy/lib/arraysetops.py b/numpy/lib/arraysetops.py
index a8b0a95bb..5cd535703 100644
--- a/numpy/lib/arraysetops.py
+++ b/numpy/lib/arraysetops.py
@@ -281,7 +281,7 @@ def setxor1d(ar1, ar2, assume_unique=False):
flag2 = flag[1:] == flag[:-1]
return aux[flag2]
-def in1d(ar1, ar2, assume_unique=False):
+def in1d(ar1, ar2, assume_unique=False, invert=False):
"""
Test whether each element of a 1-D array is also present in a second array.
@@ -297,6 +297,13 @@ def in1d(ar1, ar2, assume_unique=False):
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
-------
@@ -325,7 +332,11 @@ def in1d(ar1, ar2, assume_unique=False):
array([ True, False, True, False, True], dtype=bool)
>>> test[mask]
array([0, 2, 0])
-
+ >>> mask = np.in1d(test, states, invert=True)
+ >>> mask
+ array([False, True, False, True, False], dtype=bool)
+ >>> test[mask]
+ array([1, 5])
"""
# Ravel both arrays, behavior for the first array could be different
ar1 = np.asarray(ar1).ravel()
@@ -333,9 +344,14 @@ def in1d(ar1, ar2, assume_unique=False):
# This code is significantly faster when the condition is satisfied.
if len(ar2) < 10 * len(ar1) ** 0.145:
- mask = np.zeros(len(ar1), dtype=np.bool)
- for a in ar2:
- mask |= (ar1 == a)
+ if invert:
+ mask = np.ones(len(ar1), dtype=np.bool)
+ for a in ar2:
+ mask &= (ar1 != a)
+ else:
+ mask = np.zeros(len(ar1), dtype=np.bool)
+ for a in ar2:
+ mask |= (ar1 == a)
return mask
# Otherwise use sorting
@@ -349,8 +365,11 @@ def in1d(ar1, ar2, assume_unique=False):
# the values from the second array.
order = ar.argsort(kind='mergesort')
sar = ar[order]
- equal_adj = (sar[1:] == sar[:-1])
- flag = np.concatenate( (equal_adj, [False] ) )
+ if invert:
+ bool_ar = (sar[1:] != sar[:-1])
+ else:
+ bool_ar = (sar[1:] == sar[:-1])
+ flag = np.concatenate( (bool_ar, [invert]) )
indx = order.argsort(kind='mergesort')[:len( ar1 )]
if assume_unique:
diff --git a/numpy/lib/tests/test_arraysetops.py b/numpy/lib/tests/test_arraysetops.py
index b3c608cf8..f7f75922d 100644
--- a/numpy/lib/tests/test_arraysetops.py
+++ b/numpy/lib/tests/test_arraysetops.py
@@ -190,6 +190,15 @@ class TestSetOps(TestCase):
assert_array_equal(c, ec)
+ def test_in1d_invert(self):
+ "Test in1d's invert parameter"
+ # We use two different sizes for the b array here to test the
+ # two different paths in in1d().
+ for mult in (1, 10):
+ a = np.array([5, 4, 5, 3, 4, 4, 3, 4, 3, 5, 2, 1, 5, 5])
+ b = [2, 3, 4] * mult
+ assert_array_equal(np.invert(in1d(a, b)), in1d(a, b, invert=True))
+
def test_in1d_ravel(self):
# Test that in1d ravels its input arrays. This is not documented
# behavior however. The test is to ensure consistentency.
diff --git a/numpy/ma/extras.py b/numpy/ma/extras.py
index a809db53c..861fefad0 100644
--- a/numpy/ma/extras.py
+++ b/numpy/ma/extras.py
@@ -1121,7 +1121,7 @@ def setxor1d(ar1, ar2, assume_unique=False):
flag2 = (flag[1:] == flag[:-1])
return aux[flag2]
-def in1d(ar1, ar2, assume_unique=False):
+def in1d(ar1, ar2, assume_unique=False, invert=False):
"""
Test whether each element of an array is also present in a second
array.
@@ -1147,8 +1147,11 @@ def in1d(ar1, ar2, assume_unique=False):
# the values from the second array.
order = ar.argsort(kind='mergesort')
sar = ar[order]
- equal_adj = (sar[1:] == sar[:-1])
- flag = ma.concatenate((equal_adj, [False]))
+ if invert:
+ bool_ar = (sar[1:] != sar[:-1])
+ else:
+ bool_ar = (sar[1:] == sar[:-1])
+ flag = ma.concatenate((bool_ar, [invert]))
indx = order.argsort(kind='mergesort')[:len(ar1)]
if assume_unique:
diff --git a/numpy/ma/tests/test_extras.py b/numpy/ma/tests/test_extras.py
index b6643fc4d..d9f94a01f 100644
--- a/numpy/ma/tests/test_extras.py
+++ b/numpy/ma/tests/test_extras.py
@@ -810,6 +810,19 @@ class TestArraySetOps(TestCase):
assert_array_equal([], in1d([], []))
+ def test_in1d_invert(self):
+ "Test in1d's invert parameter"
+ a = array([1, 2, 5, 7, -1], mask=[0, 0, 0, 0, 1])
+ b = array([1, 2, 3, 4, 5, -1], mask=[0, 0, 0, 0, 0, 1])
+ assert_equal(np.invert(in1d(a, b)), in1d(a, b, invert=True))
+
+ a = array([5, 5, 2, 1, -1], mask=[0, 0, 0, 0, 1])
+ b = array([1, 5, -1], mask=[0, 0, 1])
+ assert_equal(np.invert(in1d(a, b)), in1d(a, b, invert=True))
+
+ assert_array_equal([], in1d([], [], invert=True))
+
+
def test_union1d(self):
"Test union1d"
a = array([1, 2, 5, 7, 5, -1], mask=[0, 0, 0, 0, 0, 1])