-
Notifications
You must be signed in to change notification settings - Fork 470
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
pint scalars have no shape, unlike numpy scalars #1342
Comments
This relates to a perennial discussion point in Pint about handling of scalars and arrays (e.g., #1128, #950, #753) that hasn't seen a good resolution yet. In short, this seems to just be a natural consequence of Pint Quantities being a flexible wrapper class that are equally capable of working with and without NumPy--Quantities wrapping Python scalars behave more like Python scalars and Quantities wrapping NumPy scalars behave like NumPy scalars. Though, is this still an issue you encounter when using a Pint registry with All that being said, I definitely agree about the repr. That would be a good fix! |
Oh I don't know how I didn't see #950 when I searched for previous issues! I think my issue is basically a duplicate of that one.
Kind of? Depends on whether I create the quantity with In [33]: from pint import UnitRegistry
...: ureg = UnitRegistry(force_ndarray_like=True)
In [34]: q = ureg.Quantity(2.0)
In [35]: q.shape
Out[35]: ()
In [36]: q = pint.Quantity(2.0)
In [37]: q.shape
---------------------------------------------------------------------------
AttributeError Traceback (most recent call last)
~/miniconda3/envs/py38-mamba/lib/python3.8/site-packages/pint/quantity.py in __getattr__(self, item)
1841 try:
-> 1842 return getattr(self._magnitude, item)
1843 except AttributeError:
AttributeError: 'float' object has no attribute 'shape'
During handling of the above exception, another exception occurred:
AttributeError Traceback (most recent call last)
<ipython-input-37-0fad4e80c834> in <module>
----> 1 q.shape
~/miniconda3/envs/py38-mamba/lib/python3.8/site-packages/pint/quantity.py in __getattr__(self, item)
1842 return getattr(self._magnitude, item)
1843 except AttributeError:
-> 1844 raise AttributeError(
1845 "Neither Quantity object nor its magnitude ({}) "
1846 "has attribute '{}'".format(self._magnitude, item)
AttributeError: Neither Quantity object nor its magnitude (2.0) has attribute 'shape' That's not really ideal -
What would be the fix though? If there was a I personally don't really see what the point of diverging from numpy's interface at all is. |
I suppose that this does effectively solve the problem with xarray though: pint-xarray can always require |
I can definitely see that, but from what I recall every choice in Pint is on the registry level...it just happens to be that using the global Quantity class uses the application registry, which has a default, but otherwise can be configured with
I was guessing including the type of the magnitude in some form, a la Dask, so maybe
As a user who's only worked with Pint alongside NumPy, I would tend to agree, however, I recognize that the library has been deliberately designed for use without NumPy. But, with the current state of the ecosystem, maybe that's something that merits more discussion? What are the maintainers' thoughts here? |
I suppose. Conceptually I find that a bit confusing (because how you treat scalar arrays has nothing to do with what system of units you use), but I see why it's like this.
That would be a very clear representation, but it also doesn't really follow the convention of the repr being executable. |
My thoughts about some of the raised issues are the following: Global vs Registry level flags: I don't like global variables as I think it makes things more difficult to reason about. So in pint we try to make stateless functions when state is need we keep in instances (not globally). In a way, Pint started from this idea as the registry is not module (as was in other libraries at the time) but rather an object that parses a (text) file. Having registy level flags is just setting the defaults for the registry to interact with the user. Other ways to speficy flags (not just force ndarray): We can create a sort of context manager to be able to change this flages for a block of code. Something like: with ureg.force_ndarray():
# codes goes here or more general with ureg.with_flags(force_ndarray=True, case_sensitive=False):
# codes goes here I have been recently playing with contextvars to make Breadcrumbs. I is easy to use, robust and could work for this. Requiring NumPy for Pint The choice of making Pint independent of numpy comes from the time in which wheels and conda were only a dream. NumPy was not available as binary in some platforms and I had to recompile SciPy to install it. Things have indeed changed, in a good way. However, I think that before requiring numpy it would be better to explore the old idea of making a repr: I agree with the criticism. I like Alex Martelli's views in this post. I would agree with any PR that goes in this direction. |
@jthielen We can change repr to just use the repr of the magnitude it's easy enough & just adding units to the repr. <Quantity(array(2.), 'dimensionless')>
<Quantity(array(2., dtype=float32), 'dimensionless')>
<Quantity(array([2., 3., 4., ..., 2., 3., 4.]), 'dimensionless')>
<Quantity(dask.array<array, shape=(3,), dtype=float64, chunksize=(3,), chunktype=numpy.ndarray>, 'dimensionless')>
<Quantity(2.932515646146465, 'dimensionless')>
<Quantity(Decimal('2.9325156461464651456456545649'), 'dimensionless')> using |
Pint scalars constructed from bare floats have no shape, unlike numpy scalars. For example:
This is a pretty significant departure from a numpy-like API, at least in terms of construction.
Creating a
Quantity
from a numpy array does create an object which has ashape
, but the two differently-behaving objects have the same repr!!!This should not be possible - the repr should have a one-to-one relationship with the instance - and I would be interested in submitting a PR to help fix it.
I noticed this whilst trying to create an xarray.DataArray which wraps a quantified scalar:
(@keewis you probably want to see this too)
(This is with pint version 0.17)
The text was updated successfully, but these errors were encountered: