-
-
Notifications
You must be signed in to change notification settings - Fork 11.1k
Enhance piecewise to allow functions to have arbitrary number of input arguments #5187
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
Conversation
We can't break backward compatibility here. Either a new function is needed, or the enhanced function needs to be fixed to work with old arguments. |
According to the docstring of the old function:
Thus the example
violates the condition that condlist should be a list. Here condlist is a ndarray. The old function allowed this calling syntax, but it is clearly an undocumented feature of the old function. The question is if that is a wanted behavior? For now I have allowed this behavior and removed any backward incompatibilties as far as I know. The only thing I have added is a deprecation warning if the condlist is not a list of booleans or boolean arrays. |
☔ The latest upstream changes (presumably #5985) made this pull request unmergeable. Please resolve the merge conflicts. |
☔ The latest upstream changes (presumably #6115) made this pull request unmergeable. Please resolve the merge conflicts. |
☔ The latest upstream changes (presumably #7145) made this pull request unmergeable. Please resolve the merge conflicts. |
Seems this didn't merge...would be a useful enhancement. Any update on this? |
numpy/lib/function_base.py
Outdated
@@ -838,7 +838,19 @@ class ndarray is returned. | |||
return a | |||
|
|||
|
|||
def piecewise(x, condlist, funclist, *args, **kw): | |||
def valarray(shape, value=0.0, typecode=None): |
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.
This function is just a less reliable np.full
- and it looks like it's not used anyway
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.
Can you explain how you can substitute np.piecewise with np.full?
Or, to avoid the xy problem: How would one write a conditional function that works cleanly with both 1-d numpy arrays as well as the 2-d array outputs from meshgrid?
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.
I'm commenting on valarray
, not piecewise
@hunterakins: The problem is that The best way forward would be to introduce a |
That's alright.
I still don't understand how that has to do with np.full or defining
conditional functions that work on meshgrid 2D arrays.
…On Tue, Oct 30, 2018 at 9:28 PM Eric Wieser ***@***.***> wrote:
@hunterakins <https://github.com/hunterakins>: The problem is that piecewise((x1,
x2. x3), ...) is already valid syntax, and is the same as np.piecewise(np.array([x1,
x2, x3])). We can't change that behavior without at least a deprecation
cycle.
The best way forward would be to introduce a FutureWarning when x is a
tuple, and then maybe in 1.18 the new behavior can be introduced
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#5187 (comment)>, or mute
the thread
<https://github.com/notifications/unsubscribe-auth/AVO9O4tTEUhSK3AlF2eVis26twdq0aLBks5uqSbcgaJpZM4Cus3K>
.
|
@pbrod This has been open for a while. Do you plan to come back to this ? |
@anirudh2290 Well, I am happy to complete this, but I need guidance on how to proceed. |
@pbrod According to me, looks like this enhancement would be a good to have.
Since single condition is promoted to a list of one condition, I won't mind keeping it as it is and documenting this behavior. cc @eric-wieser for a second look. |
Can we come up with a new spelling that doesn't overlap the old one? As a reminder, we currently have: np.piecewise(
arr_like,
[cond1, cond2, cond3],
[func1, func2, func3, func_default],
*func_args, **func_kwargs) One option might be pulling some magic with np.piecewise[2](
arr_like1,
arr_like2,
[cond1, cond2, cond3],
[func1, func2, func3, func_default],
*func_args, **func_kwargs) or by currying (noting that 2-argument invocations are currently not allowed): np.piecewise(
[cond1, cond2, cond3],
[func1, func2, func3, func_default])(arr_like1, arr_like2) Will edit this post if I think of more... |
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.
Looks like there are more behavior changes here than I first spotted
numpy/lib/function_base.py
Outdated
|
||
The length of `condlist` must correspond to that of `funclist`. | ||
If one extra function is given, i.e. if | ||
``len(funclist) - len(condlist) == 1``, then that extra function | ||
is the default value, used wherever all conditions are false. | ||
funclist : list of callables, f(x,*args,**kw), or scalars | ||
funclist : list of callables, f(*(xi + args), **kw), or scalars |
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.
funclist : list of callables, f(*(xi + args), **kw), or scalars | |
funclist : list of callables, f(*xi, *args, **kw), or scalars |
is also legal and probably clearer
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.
xi may be slightly misleading since these funcs run on indexed array as such which will be 1d and may not be all elements of xi.
numpy/lib/function_base.py
Outdated
# corresponding condlist as a boolean mask. This is done in reverse | ||
# order since the first choice should take precedence. |
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.
xref #16475, this is a behavior change too
numpy/lib/function_base.py
Outdated
if deprecated_ints: | ||
msg = "piecewise condlists containing integer ndarrays is deprecated " \ | ||
"and will be removed in the future. Use `.astype(bool)` to " \ | ||
"convert to bools." | ||
warnings.warn(msg, DeprecationWarning) |
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.
This change is probably sensible to extract to its own PR. Note this is missing stacklevel=2
.
assert_(y.ndim == 0) | ||
assert_(y == 0) | ||
|
||
x = 5 | ||
y = piecewise(x, [[True], [False]], [1, 0]) | ||
assert_(y.ndim == 0) | ||
assert_(y.ndim == 1) |
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.
This is a breaking change as well sadly.
Made piecewise function simpler and more general. The new piecewise function allows functions of the type f(x0, x1,.. ,xn) i.e. to have arbitrary number of input arguments that are evaluated conditionally.
The old piecewise function did allow condlist to be a single bool list/array or a single int array
(That feature was not documented in the docstring of the function, but there were tests testing this functionality.) Question is if this feature should be deprecated. For now this feature is kept in the new version.
See also: http://www.mail-archive.com/numpy-discussion@scipy.org/msg46304.html
Examples
Examples that work both in previous and current version
can be written as
or
Example that still works but should possibly be deprecated:
Examples demonstrating the new functionality