-
-
Notifications
You must be signed in to change notification settings - Fork 1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
isin: better docs, support older numpy and use dask.array.isin. #2038
Changes from 1 commit
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
:py:meth:`~xarray.DataArray.isin`Copyright (c) 2014-2018, Anaconda, Inc. and contributors | ||
All rights reserved. | ||
|
||
Redistribution and use in source and binary forms, with or without modification, | ||
are permitted provided that the following conditions are met: | ||
|
||
Redistributions of source code must retain the above copyright notice, | ||
this list of conditions and the following disclaimer. | ||
|
||
Redistributions in binary form must reproduce the above copyright notice, | ||
this list of conditions and the following disclaimer in the documentation | ||
and/or other materials provided with the distribution. | ||
|
||
Neither the name of Anaconda nor the names of any contributors may be used to | ||
endorse or promote products derived from this software without specific prior | ||
written permission. | ||
|
||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | ||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE | ||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | ||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | ||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | ||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | ||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | ||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF | ||
THE POSSIBILITY OF SUCH DAMAGE. |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
from __future__ import absolute_import, division, print_function | ||
|
||
from functools import wraps | ||
import numpy as np | ||
import dask.array as da | ||
|
||
try: | ||
from dask.array import isin | ||
except ImportError: # pragma: no cover | ||
# Copied from dask v0.17.3. | ||
# Used under the terms of Dask's license, see licenses/DASK_LICENSE. | ||
|
||
def _isin_kernel(element, test_elements, assume_unique=False): | ||
values = np.in1d(element.ravel(), test_elements, | ||
assume_unique=assume_unique) | ||
return values.reshape(element.shape + (1,) * test_elements.ndim) | ||
|
||
@wraps(getattr(np, 'isin', None)) | ||
def isin(element, test_elements, assume_unique=False, invert=False): | ||
element = da.asarray(element) | ||
test_elements = da.asarray(test_elements) | ||
element_axes = tuple(range(element.ndim)) | ||
test_axes = tuple(i + element.ndim for i in range(test_elements.ndim)) | ||
mapped = da.atop(_isin_kernel, element_axes + test_axes, | ||
element, element_axes, | ||
test_elements, test_axes, | ||
adjust_chunks={axis: lambda _: 1 for axis in test_axes}, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. E501 line too long (81 > 79 characters) |
||
dtype=bool, | ||
assume_unique=assume_unique) | ||
result = mapped.any(axis=test_axes) | ||
if invert: | ||
result = ~result | ||
return result |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -255,3 +255,96 @@ def flip(m, axis): | |
raise ValueError("axis=%i is invalid for the %i-dimensional " | ||
"input array" % (axis, m.ndim)) | ||
return m[tuple(indexer)] | ||
|
||
try: | ||
from numpy import isin | ||
except ImportError: | ||
|
||
def isin(element, test_elements, assume_unique=False, invert=False): | ||
""" | ||
Calculates `element in test_elements`, broadcasting over `element` only. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. E501 line too long (80 > 79 characters) |
||
Returns a boolean array of the same shape as `element` that is True | ||
where an element of `element` is in `test_elements` and False otherwise. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. E501 line too long (80 > 79 characters) |
||
|
||
Parameters | ||
---------- | ||
element : array_like | ||
Input array. | ||
test_elements : array_like | ||
The values against which to test each value of `element`. | ||
This argument is flattened if it is an array or array_like. | ||
See notes for behavior with non-array-like parameters. | ||
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, as if | ||
calculating `element not in test_elements`. Default is False. | ||
``np.isin(a, b, invert=True)`` is equivalent to (but faster | ||
than) ``np.invert(np.isin(a, b))``. | ||
|
||
Returns | ||
------- | ||
isin : ndarray, bool | ||
Has the same shape as `element`. The values `element[isin]` | ||
are in `test_elements`. | ||
|
||
See Also | ||
-------- | ||
in1d : Flattened version of this function. | ||
numpy.lib.arraysetops : Module with a number of other functions for | ||
performing set operations on arrays. | ||
|
||
Notes | ||
----- | ||
|
||
`isin` is an element-wise function version of the python keyword `in`. | ||
``isin(a, b)`` is roughly equivalent to | ||
``np.array([item in b for item in a])`` if `a` and `b` are 1-D sequences. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. E501 line too long (81 > 79 characters) |
||
|
||
`element` and `test_elements` are converted to arrays if they are not | ||
already. If `test_elements` is a set (or other non-sequence collection) | ||
it will be converted to an object array with one element, rather than an | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. E501 line too long (80 > 79 characters) |
||
array of the values contained in `test_elements`. This is a consequence | ||
of the `array` constructor's way of handling non-sequence collections. | ||
Converting the set to a list usually gives the desired behavior. | ||
|
||
.. versionadded:: 1.13.0 | ||
|
||
Examples | ||
-------- | ||
>>> element = 2*np.arange(4).reshape((2, 2)) | ||
>>> element | ||
array([[0, 2], | ||
[4, 6]]) | ||
>>> test_elements = [1, 2, 4, 8] | ||
>>> mask = np.isin(element, test_elements) | ||
>>> mask | ||
array([[ False, True], | ||
[ True, False]]) | ||
>>> element[mask] | ||
array([2, 4]) | ||
>>> mask = np.isin(element, test_elements, invert=True) | ||
>>> mask | ||
array([[ True, False], | ||
[ False, True]]) | ||
>>> element[mask] | ||
array([0, 6]) | ||
|
||
Because of how `array` handles sets, the following does not | ||
work as expected: | ||
|
||
>>> test_set = {1, 2, 4, 8} | ||
>>> np.isin(element, test_set) | ||
array([[ False, False], | ||
[ False, False]]) | ||
|
||
Casting the set to a list gives the expected result: | ||
|
||
>>> np.isin(element, list(test_set)) | ||
array([[ False, True], | ||
[ True, False]]) | ||
""" | ||
element = np.asarray(element) | ||
return np.in1d(element, test_elements, assume_unique=assume_unique, | ||
invert=invert).reshape(element.shape) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. W292 no newline at end of file |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Feel free to change! Thank you for adding the docs