On Thu, 2023-07-13 at 21:53 -0500, Aaron Meurer wrote:
> Does astype make sense as a ufunc?
Yes and no. Implementation wise casting is practically a ufunc.
But there are real semantic differences: Casting _must_ provide the
exact output dtype (something that ufuncs do support, you have to pass
`out=`).
If you do that, you can write a ufunc for casts though: `np.positive`
is clunky, but already ends at much the same behavior (implementation
wise it does extra steps of course).
On the other hand, a normal ufunc doesn't normally care about the
output dtype, since it must and should infer it from the inputs.
Since someone now probably thinks "but there is `dtype=`". Yes, there
is, but it doesn't have the same semantics, you would need a new
`out_dtype=`.
With you could have a slightly special `copy_ufunc` where you have to
just pass `output_dtype=` (or you get a direct copy).
Not sure if it makes sense to extend things though just to use
`__array_ufunc__`, it might make sense to simplify our casting code
(merge it into ufuncs), but maybe cast/copying is distinct enough.
Clip already *is* implemented via ufuncs (minimum, maximum, and an
internal `clip()`).
Round could probably be a ufunc, but ufuncs don't have scalar
parameters (maybe they should). And the decimals is a scalar for them.
You could of course generalize decimals to not be a scalar and then you
have a proper ufunc (with some fast-path magic for when it doesn't
change).
As Ralf said, you may also have to keep the method indirection (e.g.
because otherwise you break people using `np.around()` on pandas...).
- Sebastian
>
> Aaron Meurer
>
> On Tue, Jul 11, 2023 at 7:38 AM James Webber
> wrote:
> >
> > Hello there! First time posting here and I apologize if this
> > discussion is not new. I couldn't find it in a search.
> >
> > I've been contributing a bit to the sparse project (
> > https://github.com/pydata/sparse) and I was working on specializing
> > the behavior for single-argument ufuncs, because there is a faster
> > path for some sparse arrays if the indexes don't change at all.
> >
> > As I was working on this I noticed that `sparse` uses
> > `__array_ufunc__` on some non-ufunc methods, like `round`, `clip`,
> > and `astype`, which caused some bugs in my initial attempt. This is
> > easy enough to fix in the package, but it made me wonder if those
> > functions _could_ or _should_ be ufuncs in numpy itself.
> >
> > The full list for the sparse library is `clip`, `round`, `astype`,
> > `real`, and `imag`. There might be other candidates in numpy, those
> > are just the ones in this project.
> >
> > The benefit I see is that an implementor of `__array_ufunc__`
> > wouldn't need to implement these methods. But perhaps their
> > interfaces are too complex for ufunc-iness?
> > ___
> > NumPy-Discussion mailing list -- numpy-discussion@python.org
> > To unsubscribe send an email to numpy-discussion-le...@python.org
> > https://mail.python.org/mailman3/lists/numpy-discussion.python.org/
> > Member address: asmeu...@gmail.com
> ___
> NumPy-Discussion mailing list -- numpy-discussion@python.org
> To unsubscribe send an email to numpy-discussion-le...@python.org
> https://mail.python.org/mailman3/lists/numpy-discussion.python.org/
> Member address: sebast...@sipsolutions.net
___
NumPy-Discussion mailing list -- numpy-discussion@python.org
To unsubscribe send an email to numpy-discussion-le...@python.org
https://mail.python.org/mailman3/lists/numpy-discussion.python.org/
Member address: arch...@mail-archive.com