summaryrefslogtreecommitdiff
path: root/numpy/lib/arraysetops.py
diff options
context:
space:
mode:
authorJaime <jaime.frio@gmail.com>2018-01-31 15:35:27 +0100
committerGitHub <noreply@github.com>2018-01-31 15:35:27 +0100
commitfc86cd0840854b0542fbf3619ebbd272030e7dd7 (patch)
tree1f9d2447bfd7c503e03d4afa936b1903d210287c /numpy/lib/arraysetops.py
parentbb7b12672fe7b68c7776a7f757741d4632001bf3 (diff)
parentf80e20cfcf0728e068933cd5de9575db8ac3f803 (diff)
downloadnumpy-fc86cd0840854b0542fbf3619ebbd272030e7dd7.tar.gz
Merge pull request #10498 from eric-wieser/maint-unique
MAINT: Remove special cases in np.unique
Diffstat (limited to 'numpy/lib/arraysetops.py')
-rw-r--r--numpy/lib/arraysetops.py75
1 files changed, 35 insertions, 40 deletions
diff --git a/numpy/lib/arraysetops.py b/numpy/lib/arraysetops.py
index b1e74dc74..e6ff5bf38 100644
--- a/numpy/lib/arraysetops.py
+++ b/numpy/lib/arraysetops.py
@@ -110,16 +110,25 @@ def ediff1d(ary, to_end=None, to_begin=None):
return result
+def _unpack_tuple(x):
+ """ Unpacks one-element tuples for use as return values """
+ if len(x) == 1:
+ return x[0]
+ else:
+ return x
+
+
def unique(ar, return_index=False, return_inverse=False,
return_counts=False, axis=None):
"""
Find the unique elements of an array.
Returns the sorted unique elements of an array. There are three optional
- outputs in addition to the unique elements: the indices of the input array
- that give the unique values, the indices of the unique array that
- reconstruct the input array, and the number of times each unique value
- comes up in the input array.
+ outputs in addition to the unique elements:
+
+ * the indices of the input array that give the unique values
+ * the indices of the unique array that reconstruct the input array
+ * the number of times each unique value comes up in the input array
Parameters
----------
@@ -211,7 +220,9 @@ def unique(ar, return_index=False, return_inverse=False,
"""
ar = np.asanyarray(ar)
if axis is None:
- return _unique1d(ar, return_index, return_inverse, return_counts)
+ ret = _unique1d(ar, return_index, return_inverse, return_counts)
+ return _unpack_tuple(ret)
+
if not (-ar.ndim <= axis < ar.ndim):
raise ValueError('Invalid axis kwarg specified for unique')
@@ -245,11 +256,9 @@ def unique(ar, return_index=False, return_inverse=False,
output = _unique1d(consolidated, return_index,
return_inverse, return_counts)
- if not (return_index or return_inverse or return_counts):
- return reshape_uniq(output)
- else:
- uniq = reshape_uniq(output[0])
- return (uniq,) + output[1:]
+ output = (reshape_uniq(output[0]),) + output[1:]
+ return _unpack_tuple(output)
+
def _unique1d(ar, return_index=False, return_inverse=False,
return_counts=False):
@@ -259,20 +268,6 @@ def _unique1d(ar, return_index=False, return_inverse=False,
ar = np.asanyarray(ar).flatten()
optional_indices = return_index or return_inverse
- optional_returns = optional_indices or return_counts
-
- if ar.size == 0:
- if not optional_returns:
- ret = ar
- else:
- ret = (ar,)
- if return_index:
- ret += (np.empty(0, np.intp),)
- if return_inverse:
- ret += (np.empty(0, np.intp),)
- if return_counts:
- ret += (np.empty(0, np.intp),)
- return ret
if optional_indices:
perm = ar.argsort(kind='mergesort' if return_index else 'quicksort')
@@ -280,24 +275,24 @@ def _unique1d(ar, return_index=False, return_inverse=False,
else:
ar.sort()
aux = ar
- flag = np.concatenate(([True], aux[1:] != aux[:-1]))
-
- if not optional_returns:
- ret = aux[flag]
- else:
- ret = (aux[flag],)
- if return_index:
- ret += (perm[flag],)
- if return_inverse:
- iflag = np.cumsum(flag) - 1
- inv_idx = np.empty(ar.shape, dtype=np.intp)
- inv_idx[perm] = iflag
- ret += (inv_idx,)
- if return_counts:
- idx = np.concatenate(np.nonzero(flag) + ([ar.size],))
- ret += (np.diff(idx),)
+ mask = np.empty(aux.shape, dtype=np.bool_)
+ mask[:1] = True
+ mask[1:] = aux[1:] != aux[:-1]
+
+ ret = (aux[mask],)
+ if return_index:
+ ret += (perm[mask],)
+ if return_inverse:
+ imask = np.cumsum(mask) - 1
+ inv_idx = np.empty(mask.shape, dtype=np.intp)
+ inv_idx[perm] = imask
+ ret += (inv_idx,)
+ if return_counts:
+ idx = np.concatenate(np.nonzero(mask) + ([mask.size],))
+ ret += (np.diff(idx),)
return ret
+
def intersect1d(ar1, ar2, assume_unique=False):
"""
Find the intersection of two arrays.