Skip to content
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

Handle array creation functions such as np.asanyarray #1406

Open
Illviljan opened this issue Nov 3, 2021 · 2 comments · May be fixed by #1669
Open

Handle array creation functions such as np.asanyarray #1406

Illviljan opened this issue Nov 3, 2021 · 2 comments · May be fixed by #1669

Comments

@Illviljan
Copy link

It's common for downstream packages to force inputs to numpy-likes using np.asarray, np.asanyarray etc. These have a like argument to handle duckarrays, it would be nice if pint handled these methods. Dask supports this if you want ideas how to implement it.

import numpy as np 
import pint
import dask.array as da

a = np.array([1, 2, 3])
aa = pint.Quantity(a, "m")
np.asanyarray(a, like=aa)
Traceback (most recent call last):

  File "<ipython-input-7-59dc788bb8ad>", line 1, in <module>
    np.asanyarray(a, like=aa)

TypeError: no implementation found for 'numpy.asanyarray' on types that implement __array_function__: [<class 'pint.quantity.Quantity'>]

# dask handles this just fine:
np.asanyarray(a, like=da.array(a))
dask.array<array, shape=(3,), dtype=int32, chunksize=(3,), chunktype=numpy.ndarray>
@jthielen
Copy link
Contributor

jthielen commented Nov 3, 2021

This is unfortunately not well-defined for Pint Quantities, as a single like argument isn't enough info to unambiguously specify the output (is it "like" in just the array type sense, or "like" also in units?), as alluded to previously in #882. Also, if we want this like argument behavior to be consistent with np.ones_like, np.zeros_like, and np.full_like as they're currently implemented, then this would be a no-op (although, including a Pint-specific warning may be more useful than the current TypeError). That being said, if there is a desire to change the np.*_like behavior (#882) and so also take advantage of these NEP-35 additions, then that could definitely be considered!

@Illviljan
Copy link
Author

Illviljan commented Nov 3, 2021

I think it should be array type and units. You'd lose the point of pint if the units were forgotten:

import numpy as np
import pint
import dask.array as da


def torque(r, F, like_r=None, like_F=None):
    """Low level numpy-like only implementation from another package."""
    r = np.asanyarray(r, like=like_r) if like_r is not None else np.asanyarray(r)
    F = np.asanyarray(F, like=like_F) if like_F is not None else np.asanyarray(F)

    return r * F


def torque_pint(r, F):
    """High level wrapper adding units"""
    like_r = pint.Quantity([], "m")
    like_F = pint.Quantity([], "N")
    return torque(r, F, like_r=like_r, like_F=like_F)  # [Nm]


def torque_dask(r, F):
    """High level wrapper adding dask"""
    like_r = da.array([])
    like_F = da.array([])
    return torque(r, F, like_r=like_r, like_F=like_F)


torque_pint(2, 3)
Traceback (most recent call last):

  File "<ipython-input-44-2b30fd66181f>", line 1, in <module>
    torque_pint(2, 3)

  File "<ipython-input-42-815053e56d26>", line 18, in torque_pint
    return torque(r, F, like_r=like_r, like_F=like_F)  # [Nm]

  File "<ipython-input-42-815053e56d26>", line 8, in torque
    r = np.asanyarray(r, like=like_r) if like_r is not None else np.asanyarray(r)

TypeError: no implementation found for 'numpy.asanyarray' on types that implement __array_function__: [<class 'pint.quantity.Quantity'>]


torque_dask(2, 3)
Out[45]: dask.array<mul, shape=(), dtype=int32, chunksize=(), chunktype=numpy.ndarray>

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants