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 <jamestweb...@gmail.com>
> 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

Reply via email to