Chris@87
|
1 """
|
Chris@87
|
2 Set operations for 1D numeric arrays based on sorting.
|
Chris@87
|
3
|
Chris@87
|
4 :Contains:
|
Chris@87
|
5 ediff1d,
|
Chris@87
|
6 unique,
|
Chris@87
|
7 intersect1d,
|
Chris@87
|
8 setxor1d,
|
Chris@87
|
9 in1d,
|
Chris@87
|
10 union1d,
|
Chris@87
|
11 setdiff1d
|
Chris@87
|
12
|
Chris@87
|
13 :Notes:
|
Chris@87
|
14
|
Chris@87
|
15 For floating point arrays, inaccurate results may appear due to usual round-off
|
Chris@87
|
16 and floating point comparison issues.
|
Chris@87
|
17
|
Chris@87
|
18 Speed could be gained in some operations by an implementation of
|
Chris@87
|
19 sort(), that can provide directly the permutation vectors, avoiding
|
Chris@87
|
20 thus calls to argsort().
|
Chris@87
|
21
|
Chris@87
|
22 To do: Optionally return indices analogously to unique for all functions.
|
Chris@87
|
23
|
Chris@87
|
24 :Author: Robert Cimrman
|
Chris@87
|
25
|
Chris@87
|
26 """
|
Chris@87
|
27 from __future__ import division, absolute_import, print_function
|
Chris@87
|
28
|
Chris@87
|
29 import numpy as np
|
Chris@87
|
30
|
Chris@87
|
31
|
Chris@87
|
32 __all__ = [
|
Chris@87
|
33 'ediff1d', 'intersect1d', 'setxor1d', 'union1d', 'setdiff1d', 'unique',
|
Chris@87
|
34 'in1d'
|
Chris@87
|
35 ]
|
Chris@87
|
36
|
Chris@87
|
37
|
Chris@87
|
38 def ediff1d(ary, to_end=None, to_begin=None):
|
Chris@87
|
39 """
|
Chris@87
|
40 The differences between consecutive elements of an array.
|
Chris@87
|
41
|
Chris@87
|
42 Parameters
|
Chris@87
|
43 ----------
|
Chris@87
|
44 ary : array_like
|
Chris@87
|
45 If necessary, will be flattened before the differences are taken.
|
Chris@87
|
46 to_end : array_like, optional
|
Chris@87
|
47 Number(s) to append at the end of the returned differences.
|
Chris@87
|
48 to_begin : array_like, optional
|
Chris@87
|
49 Number(s) to prepend at the beginning of the returned differences.
|
Chris@87
|
50
|
Chris@87
|
51 Returns
|
Chris@87
|
52 -------
|
Chris@87
|
53 ediff1d : ndarray
|
Chris@87
|
54 The differences. Loosely, this is ``ary.flat[1:] - ary.flat[:-1]``.
|
Chris@87
|
55
|
Chris@87
|
56 See Also
|
Chris@87
|
57 --------
|
Chris@87
|
58 diff, gradient
|
Chris@87
|
59
|
Chris@87
|
60 Notes
|
Chris@87
|
61 -----
|
Chris@87
|
62 When applied to masked arrays, this function drops the mask information
|
Chris@87
|
63 if the `to_begin` and/or `to_end` parameters are used.
|
Chris@87
|
64
|
Chris@87
|
65 Examples
|
Chris@87
|
66 --------
|
Chris@87
|
67 >>> x = np.array([1, 2, 4, 7, 0])
|
Chris@87
|
68 >>> np.ediff1d(x)
|
Chris@87
|
69 array([ 1, 2, 3, -7])
|
Chris@87
|
70
|
Chris@87
|
71 >>> np.ediff1d(x, to_begin=-99, to_end=np.array([88, 99]))
|
Chris@87
|
72 array([-99, 1, 2, 3, -7, 88, 99])
|
Chris@87
|
73
|
Chris@87
|
74 The returned array is always 1D.
|
Chris@87
|
75
|
Chris@87
|
76 >>> y = [[1, 2, 4], [1, 6, 24]]
|
Chris@87
|
77 >>> np.ediff1d(y)
|
Chris@87
|
78 array([ 1, 2, -3, 5, 18])
|
Chris@87
|
79
|
Chris@87
|
80 """
|
Chris@87
|
81 ary = np.asanyarray(ary).flat
|
Chris@87
|
82 ed = ary[1:] - ary[:-1]
|
Chris@87
|
83 arrays = [ed]
|
Chris@87
|
84 if to_begin is not None:
|
Chris@87
|
85 arrays.insert(0, to_begin)
|
Chris@87
|
86 if to_end is not None:
|
Chris@87
|
87 arrays.append(to_end)
|
Chris@87
|
88
|
Chris@87
|
89 if len(arrays) != 1:
|
Chris@87
|
90 # We'll save ourselves a copy of a potentially large array in
|
Chris@87
|
91 # the common case where neither to_begin or to_end was given.
|
Chris@87
|
92 ed = np.hstack(arrays)
|
Chris@87
|
93
|
Chris@87
|
94 return ed
|
Chris@87
|
95
|
Chris@87
|
96 def unique(ar, return_index=False, return_inverse=False, return_counts=False):
|
Chris@87
|
97 """
|
Chris@87
|
98 Find the unique elements of an array.
|
Chris@87
|
99
|
Chris@87
|
100 Returns the sorted unique elements of an array. There are two optional
|
Chris@87
|
101 outputs in addition to the unique elements: the indices of the input array
|
Chris@87
|
102 that give the unique values, and the indices of the unique array that
|
Chris@87
|
103 reconstruct the input array.
|
Chris@87
|
104
|
Chris@87
|
105 Parameters
|
Chris@87
|
106 ----------
|
Chris@87
|
107 ar : array_like
|
Chris@87
|
108 Input array. This will be flattened if it is not already 1-D.
|
Chris@87
|
109 return_index : bool, optional
|
Chris@87
|
110 If True, also return the indices of `ar` that result in the unique
|
Chris@87
|
111 array.
|
Chris@87
|
112 return_inverse : bool, optional
|
Chris@87
|
113 If True, also return the indices of the unique array that can be used
|
Chris@87
|
114 to reconstruct `ar`.
|
Chris@87
|
115 return_counts : bool, optional
|
Chris@87
|
116 .. versionadded:: 1.9.0
|
Chris@87
|
117 If True, also return the number of times each unique value comes up
|
Chris@87
|
118 in `ar`.
|
Chris@87
|
119
|
Chris@87
|
120 Returns
|
Chris@87
|
121 -------
|
Chris@87
|
122 unique : ndarray
|
Chris@87
|
123 The sorted unique values.
|
Chris@87
|
124 unique_indices : ndarray, optional
|
Chris@87
|
125 The indices of the first occurrences of the unique values in the
|
Chris@87
|
126 (flattened) original array. Only provided if `return_index` is True.
|
Chris@87
|
127 unique_inverse : ndarray, optional
|
Chris@87
|
128 The indices to reconstruct the (flattened) original array from the
|
Chris@87
|
129 unique array. Only provided if `return_inverse` is True.
|
Chris@87
|
130 unique_counts : ndarray, optional
|
Chris@87
|
131 .. versionadded:: 1.9.0
|
Chris@87
|
132 The number of times each of the unique values comes up in the
|
Chris@87
|
133 original array. Only provided if `return_counts` is True.
|
Chris@87
|
134
|
Chris@87
|
135 See Also
|
Chris@87
|
136 --------
|
Chris@87
|
137 numpy.lib.arraysetops : Module with a number of other functions for
|
Chris@87
|
138 performing set operations on arrays.
|
Chris@87
|
139
|
Chris@87
|
140 Examples
|
Chris@87
|
141 --------
|
Chris@87
|
142 >>> np.unique([1, 1, 2, 2, 3, 3])
|
Chris@87
|
143 array([1, 2, 3])
|
Chris@87
|
144 >>> a = np.array([[1, 1], [2, 3]])
|
Chris@87
|
145 >>> np.unique(a)
|
Chris@87
|
146 array([1, 2, 3])
|
Chris@87
|
147
|
Chris@87
|
148 Return the indices of the original array that give the unique values:
|
Chris@87
|
149
|
Chris@87
|
150 >>> a = np.array(['a', 'b', 'b', 'c', 'a'])
|
Chris@87
|
151 >>> u, indices = np.unique(a, return_index=True)
|
Chris@87
|
152 >>> u
|
Chris@87
|
153 array(['a', 'b', 'c'],
|
Chris@87
|
154 dtype='|S1')
|
Chris@87
|
155 >>> indices
|
Chris@87
|
156 array([0, 1, 3])
|
Chris@87
|
157 >>> a[indices]
|
Chris@87
|
158 array(['a', 'b', 'c'],
|
Chris@87
|
159 dtype='|S1')
|
Chris@87
|
160
|
Chris@87
|
161 Reconstruct the input array from the unique values:
|
Chris@87
|
162
|
Chris@87
|
163 >>> a = np.array([1, 2, 6, 4, 2, 3, 2])
|
Chris@87
|
164 >>> u, indices = np.unique(a, return_inverse=True)
|
Chris@87
|
165 >>> u
|
Chris@87
|
166 array([1, 2, 3, 4, 6])
|
Chris@87
|
167 >>> indices
|
Chris@87
|
168 array([0, 1, 4, 3, 1, 2, 1])
|
Chris@87
|
169 >>> u[indices]
|
Chris@87
|
170 array([1, 2, 6, 4, 2, 3, 2])
|
Chris@87
|
171
|
Chris@87
|
172 """
|
Chris@87
|
173 ar = np.asanyarray(ar).flatten()
|
Chris@87
|
174
|
Chris@87
|
175 optional_indices = return_index or return_inverse
|
Chris@87
|
176 optional_returns = optional_indices or return_counts
|
Chris@87
|
177
|
Chris@87
|
178 if ar.size == 0:
|
Chris@87
|
179 if not optional_returns:
|
Chris@87
|
180 ret = ar
|
Chris@87
|
181 else:
|
Chris@87
|
182 ret = (ar,)
|
Chris@87
|
183 if return_index:
|
Chris@87
|
184 ret += (np.empty(0, np.bool),)
|
Chris@87
|
185 if return_inverse:
|
Chris@87
|
186 ret += (np.empty(0, np.bool),)
|
Chris@87
|
187 if return_counts:
|
Chris@87
|
188 ret += (np.empty(0, np.intp),)
|
Chris@87
|
189 return ret
|
Chris@87
|
190
|
Chris@87
|
191 if optional_indices:
|
Chris@87
|
192 perm = ar.argsort(kind='mergesort' if return_index else 'quicksort')
|
Chris@87
|
193 aux = ar[perm]
|
Chris@87
|
194 else:
|
Chris@87
|
195 ar.sort()
|
Chris@87
|
196 aux = ar
|
Chris@87
|
197 flag = np.concatenate(([True], aux[1:] != aux[:-1]))
|
Chris@87
|
198
|
Chris@87
|
199 if not optional_returns:
|
Chris@87
|
200 ret = aux[flag]
|
Chris@87
|
201 else:
|
Chris@87
|
202 ret = (aux[flag],)
|
Chris@87
|
203 if return_index:
|
Chris@87
|
204 ret += (perm[flag],)
|
Chris@87
|
205 if return_inverse:
|
Chris@87
|
206 iflag = np.cumsum(flag) - 1
|
Chris@87
|
207 iperm = perm.argsort()
|
Chris@87
|
208 ret += (np.take(iflag, iperm),)
|
Chris@87
|
209 if return_counts:
|
Chris@87
|
210 idx = np.concatenate(np.nonzero(flag) + ([ar.size],))
|
Chris@87
|
211 ret += (np.diff(idx),)
|
Chris@87
|
212 return ret
|
Chris@87
|
213
|
Chris@87
|
214 def intersect1d(ar1, ar2, assume_unique=False):
|
Chris@87
|
215 """
|
Chris@87
|
216 Find the intersection of two arrays.
|
Chris@87
|
217
|
Chris@87
|
218 Return the sorted, unique values that are in both of the input arrays.
|
Chris@87
|
219
|
Chris@87
|
220 Parameters
|
Chris@87
|
221 ----------
|
Chris@87
|
222 ar1, ar2 : array_like
|
Chris@87
|
223 Input arrays.
|
Chris@87
|
224 assume_unique : bool
|
Chris@87
|
225 If True, the input arrays are both assumed to be unique, which
|
Chris@87
|
226 can speed up the calculation. Default is False.
|
Chris@87
|
227
|
Chris@87
|
228 Returns
|
Chris@87
|
229 -------
|
Chris@87
|
230 intersect1d : ndarray
|
Chris@87
|
231 Sorted 1D array of common and unique elements.
|
Chris@87
|
232
|
Chris@87
|
233 See Also
|
Chris@87
|
234 --------
|
Chris@87
|
235 numpy.lib.arraysetops : Module with a number of other functions for
|
Chris@87
|
236 performing set operations on arrays.
|
Chris@87
|
237
|
Chris@87
|
238 Examples
|
Chris@87
|
239 --------
|
Chris@87
|
240 >>> np.intersect1d([1, 3, 4, 3], [3, 1, 2, 1])
|
Chris@87
|
241 array([1, 3])
|
Chris@87
|
242
|
Chris@87
|
243 """
|
Chris@87
|
244 if not assume_unique:
|
Chris@87
|
245 # Might be faster than unique( intersect1d( ar1, ar2 ) )?
|
Chris@87
|
246 ar1 = unique(ar1)
|
Chris@87
|
247 ar2 = unique(ar2)
|
Chris@87
|
248 aux = np.concatenate((ar1, ar2))
|
Chris@87
|
249 aux.sort()
|
Chris@87
|
250 return aux[:-1][aux[1:] == aux[:-1]]
|
Chris@87
|
251
|
Chris@87
|
252 def setxor1d(ar1, ar2, assume_unique=False):
|
Chris@87
|
253 """
|
Chris@87
|
254 Find the set exclusive-or of two arrays.
|
Chris@87
|
255
|
Chris@87
|
256 Return the sorted, unique values that are in only one (not both) of the
|
Chris@87
|
257 input arrays.
|
Chris@87
|
258
|
Chris@87
|
259 Parameters
|
Chris@87
|
260 ----------
|
Chris@87
|
261 ar1, ar2 : array_like
|
Chris@87
|
262 Input arrays.
|
Chris@87
|
263 assume_unique : bool
|
Chris@87
|
264 If True, the input arrays are both assumed to be unique, which
|
Chris@87
|
265 can speed up the calculation. Default is False.
|
Chris@87
|
266
|
Chris@87
|
267 Returns
|
Chris@87
|
268 -------
|
Chris@87
|
269 setxor1d : ndarray
|
Chris@87
|
270 Sorted 1D array of unique values that are in only one of the input
|
Chris@87
|
271 arrays.
|
Chris@87
|
272
|
Chris@87
|
273 Examples
|
Chris@87
|
274 --------
|
Chris@87
|
275 >>> a = np.array([1, 2, 3, 2, 4])
|
Chris@87
|
276 >>> b = np.array([2, 3, 5, 7, 5])
|
Chris@87
|
277 >>> np.setxor1d(a,b)
|
Chris@87
|
278 array([1, 4, 5, 7])
|
Chris@87
|
279
|
Chris@87
|
280 """
|
Chris@87
|
281 if not assume_unique:
|
Chris@87
|
282 ar1 = unique(ar1)
|
Chris@87
|
283 ar2 = unique(ar2)
|
Chris@87
|
284
|
Chris@87
|
285 aux = np.concatenate((ar1, ar2))
|
Chris@87
|
286 if aux.size == 0:
|
Chris@87
|
287 return aux
|
Chris@87
|
288
|
Chris@87
|
289 aux.sort()
|
Chris@87
|
290 # flag = ediff1d( aux, to_end = 1, to_begin = 1 ) == 0
|
Chris@87
|
291 flag = np.concatenate(([True], aux[1:] != aux[:-1], [True]))
|
Chris@87
|
292 # flag2 = ediff1d( flag ) == 0
|
Chris@87
|
293 flag2 = flag[1:] == flag[:-1]
|
Chris@87
|
294 return aux[flag2]
|
Chris@87
|
295
|
Chris@87
|
296 def in1d(ar1, ar2, assume_unique=False, invert=False):
|
Chris@87
|
297 """
|
Chris@87
|
298 Test whether each element of a 1-D array is also present in a second array.
|
Chris@87
|
299
|
Chris@87
|
300 Returns a boolean array the same length as `ar1` that is True
|
Chris@87
|
301 where an element of `ar1` is in `ar2` and False otherwise.
|
Chris@87
|
302
|
Chris@87
|
303 Parameters
|
Chris@87
|
304 ----------
|
Chris@87
|
305 ar1 : (M,) array_like
|
Chris@87
|
306 Input array.
|
Chris@87
|
307 ar2 : array_like
|
Chris@87
|
308 The values against which to test each value of `ar1`.
|
Chris@87
|
309 assume_unique : bool, optional
|
Chris@87
|
310 If True, the input arrays are both assumed to be unique, which
|
Chris@87
|
311 can speed up the calculation. Default is False.
|
Chris@87
|
312 invert : bool, optional
|
Chris@87
|
313 If True, the values in the returned array are inverted (that is,
|
Chris@87
|
314 False where an element of `ar1` is in `ar2` and True otherwise).
|
Chris@87
|
315 Default is False. ``np.in1d(a, b, invert=True)`` is equivalent
|
Chris@87
|
316 to (but is faster than) ``np.invert(in1d(a, b))``.
|
Chris@87
|
317
|
Chris@87
|
318 .. versionadded:: 1.8.0
|
Chris@87
|
319
|
Chris@87
|
320 Returns
|
Chris@87
|
321 -------
|
Chris@87
|
322 in1d : (M,) ndarray, bool
|
Chris@87
|
323 The values `ar1[in1d]` are in `ar2`.
|
Chris@87
|
324
|
Chris@87
|
325 See Also
|
Chris@87
|
326 --------
|
Chris@87
|
327 numpy.lib.arraysetops : Module with a number of other functions for
|
Chris@87
|
328 performing set operations on arrays.
|
Chris@87
|
329
|
Chris@87
|
330 Notes
|
Chris@87
|
331 -----
|
Chris@87
|
332 `in1d` can be considered as an element-wise function version of the
|
Chris@87
|
333 python keyword `in`, for 1-D sequences. ``in1d(a, b)`` is roughly
|
Chris@87
|
334 equivalent to ``np.array([item in b for item in a])``.
|
Chris@87
|
335
|
Chris@87
|
336 .. versionadded:: 1.4.0
|
Chris@87
|
337
|
Chris@87
|
338 Examples
|
Chris@87
|
339 --------
|
Chris@87
|
340 >>> test = np.array([0, 1, 2, 5, 0])
|
Chris@87
|
341 >>> states = [0, 2]
|
Chris@87
|
342 >>> mask = np.in1d(test, states)
|
Chris@87
|
343 >>> mask
|
Chris@87
|
344 array([ True, False, True, False, True], dtype=bool)
|
Chris@87
|
345 >>> test[mask]
|
Chris@87
|
346 array([0, 2, 0])
|
Chris@87
|
347 >>> mask = np.in1d(test, states, invert=True)
|
Chris@87
|
348 >>> mask
|
Chris@87
|
349 array([False, True, False, True, False], dtype=bool)
|
Chris@87
|
350 >>> test[mask]
|
Chris@87
|
351 array([1, 5])
|
Chris@87
|
352 """
|
Chris@87
|
353 # Ravel both arrays, behavior for the first array could be different
|
Chris@87
|
354 ar1 = np.asarray(ar1).ravel()
|
Chris@87
|
355 ar2 = np.asarray(ar2).ravel()
|
Chris@87
|
356
|
Chris@87
|
357 # This code is significantly faster when the condition is satisfied.
|
Chris@87
|
358 if len(ar2) < 10 * len(ar1) ** 0.145:
|
Chris@87
|
359 if invert:
|
Chris@87
|
360 mask = np.ones(len(ar1), dtype=np.bool)
|
Chris@87
|
361 for a in ar2:
|
Chris@87
|
362 mask &= (ar1 != a)
|
Chris@87
|
363 else:
|
Chris@87
|
364 mask = np.zeros(len(ar1), dtype=np.bool)
|
Chris@87
|
365 for a in ar2:
|
Chris@87
|
366 mask |= (ar1 == a)
|
Chris@87
|
367 return mask
|
Chris@87
|
368
|
Chris@87
|
369 # Otherwise use sorting
|
Chris@87
|
370 if not assume_unique:
|
Chris@87
|
371 ar1, rev_idx = np.unique(ar1, return_inverse=True)
|
Chris@87
|
372 ar2 = np.unique(ar2)
|
Chris@87
|
373
|
Chris@87
|
374 ar = np.concatenate((ar1, ar2))
|
Chris@87
|
375 # We need this to be a stable sort, so always use 'mergesort'
|
Chris@87
|
376 # here. The values from the first array should always come before
|
Chris@87
|
377 # the values from the second array.
|
Chris@87
|
378 order = ar.argsort(kind='mergesort')
|
Chris@87
|
379 sar = ar[order]
|
Chris@87
|
380 if invert:
|
Chris@87
|
381 bool_ar = (sar[1:] != sar[:-1])
|
Chris@87
|
382 else:
|
Chris@87
|
383 bool_ar = (sar[1:] == sar[:-1])
|
Chris@87
|
384 flag = np.concatenate((bool_ar, [invert]))
|
Chris@87
|
385 indx = order.argsort(kind='mergesort')[:len(ar1)]
|
Chris@87
|
386
|
Chris@87
|
387 if assume_unique:
|
Chris@87
|
388 return flag[indx]
|
Chris@87
|
389 else:
|
Chris@87
|
390 return flag[indx][rev_idx]
|
Chris@87
|
391
|
Chris@87
|
392 def union1d(ar1, ar2):
|
Chris@87
|
393 """
|
Chris@87
|
394 Find the union of two arrays.
|
Chris@87
|
395
|
Chris@87
|
396 Return the unique, sorted array of values that are in either of the two
|
Chris@87
|
397 input arrays.
|
Chris@87
|
398
|
Chris@87
|
399 Parameters
|
Chris@87
|
400 ----------
|
Chris@87
|
401 ar1, ar2 : array_like
|
Chris@87
|
402 Input arrays. They are flattened if they are not already 1D.
|
Chris@87
|
403
|
Chris@87
|
404 Returns
|
Chris@87
|
405 -------
|
Chris@87
|
406 union1d : ndarray
|
Chris@87
|
407 Unique, sorted union of the input arrays.
|
Chris@87
|
408
|
Chris@87
|
409 See Also
|
Chris@87
|
410 --------
|
Chris@87
|
411 numpy.lib.arraysetops : Module with a number of other functions for
|
Chris@87
|
412 performing set operations on arrays.
|
Chris@87
|
413
|
Chris@87
|
414 Examples
|
Chris@87
|
415 --------
|
Chris@87
|
416 >>> np.union1d([-1, 0, 1], [-2, 0, 2])
|
Chris@87
|
417 array([-2, -1, 0, 1, 2])
|
Chris@87
|
418
|
Chris@87
|
419 """
|
Chris@87
|
420 return unique(np.concatenate((ar1, ar2)))
|
Chris@87
|
421
|
Chris@87
|
422 def setdiff1d(ar1, ar2, assume_unique=False):
|
Chris@87
|
423 """
|
Chris@87
|
424 Find the set difference of two arrays.
|
Chris@87
|
425
|
Chris@87
|
426 Return the sorted, unique values in `ar1` that are not in `ar2`.
|
Chris@87
|
427
|
Chris@87
|
428 Parameters
|
Chris@87
|
429 ----------
|
Chris@87
|
430 ar1 : array_like
|
Chris@87
|
431 Input array.
|
Chris@87
|
432 ar2 : array_like
|
Chris@87
|
433 Input comparison array.
|
Chris@87
|
434 assume_unique : bool
|
Chris@87
|
435 If True, the input arrays are both assumed to be unique, which
|
Chris@87
|
436 can speed up the calculation. Default is False.
|
Chris@87
|
437
|
Chris@87
|
438 Returns
|
Chris@87
|
439 -------
|
Chris@87
|
440 setdiff1d : ndarray
|
Chris@87
|
441 Sorted 1D array of values in `ar1` that are not in `ar2`.
|
Chris@87
|
442
|
Chris@87
|
443 See Also
|
Chris@87
|
444 --------
|
Chris@87
|
445 numpy.lib.arraysetops : Module with a number of other functions for
|
Chris@87
|
446 performing set operations on arrays.
|
Chris@87
|
447
|
Chris@87
|
448 Examples
|
Chris@87
|
449 --------
|
Chris@87
|
450 >>> a = np.array([1, 2, 3, 2, 4, 1])
|
Chris@87
|
451 >>> b = np.array([3, 4, 5, 6])
|
Chris@87
|
452 >>> np.setdiff1d(a, b)
|
Chris@87
|
453 array([1, 2])
|
Chris@87
|
454
|
Chris@87
|
455 """
|
Chris@87
|
456 if not assume_unique:
|
Chris@87
|
457 ar1 = unique(ar1)
|
Chris@87
|
458 ar2 = unique(ar2)
|
Chris@87
|
459 aux = in1d(ar1, ar2, assume_unique=True)
|
Chris@87
|
460 if aux.size == 0:
|
Chris@87
|
461 return aux
|
Chris@87
|
462 else:
|
Chris@87
|
463 return np.asarray(ar1)[aux == 0]
|