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

np.full for Quantities #10836

Open
nbiederbeck opened this issue Oct 12, 2020 · 14 comments · May be fixed by #16138
Open

np.full for Quantities #10836

nbiederbeck opened this issue Oct 12, 2020 · 14 comments · May be fixed by #16138

Comments

@nbiederbeck
Copy link

Description

I try to do

my_quantity = u.Quantity(1, u.m)
np.full(10, my_quantity)

but get

UnitConversionError: 'm' (length) and '' (dimensionless) are not convertible

What I want is what I get via

u.Quantity(np.full(10, my_quantity.value), unit=my_quantity.unit)
>>> [1, 1, 1, 1, 1, 1, 1, 1, 1, 1] m

but the first version is so much cleaner.

Is there a (better) way to do this, or a chance to implement this?

@pllim
Copy link
Member

pllim commented Oct 12, 2020

You could also do:

np.full(10, 1) << u.m 

But for the original request, perhaps @mhvk has an idea. If it is indeed a "won't fix," we should probably add it to https://docs.astropy.org/en/latest/known_issues.html .

@mhvk
Copy link
Contributor

mhvk commented Oct 12, 2020

@nbiederbeck - thanks for raising the issue! Unfortunately, this is one of the very few numpy functions which we still cannot override (numpy allows only to override functions that take an array as an argument, so np.full_like is possible, though there is some work on trying to change this). I think @pllim's suggestion is probably the cleanest that we can do at the moment.

@pllim - you are right that we should add this to the known issues. One similarly cannot do np.zeros, np.ones, and np.empty.

@nbiederbeck
Copy link
Author

Ok, thanks for your quick answers!

@astrojuanlu
Copy link
Member

we should add this to the known issues. One similarly cannot do np.zeros, np.ones, and np.empty.

If you are okay then, until a proper fix is in place, this would be simple enough for new contributors.

@pllim
Copy link
Member

pllim commented Oct 13, 2020

this would be simple enough for new contributors

@astrojuanlu , to avoid confusing new contributor, I wonder if we should open a new issue just to address the doc part of things.

@astrojuanlu
Copy link
Member

#10845

@mhvk
Copy link
Contributor

mhvk commented Oct 13, 2020

@astrojuanlu - thanks for raising the new issue. I marked the present one 'upstream fix required' since there are developments to make it work for numpy >=1.20 (though it would need an additional like= argument), but discussion is still ongoing - numpy/numpy#17075

@pentschev
Copy link

I just saw this due to the xref in numpy/numpy#17075, it seems like np.full_like would be of use (there's no need for like=), and that's available since NumPy 1.16 (or maybe earlier). I have zero experience with astropy so I can't really comment on specifics for it and perhaps can be implemented/used here. np.full_like is very useful in other libraries such as CuPy, for example:

In [1]: import numpy as np, cupy as cp

In [2]: a = cp.ones(3)

In [3]: b = np.full_like(a, 7)

In [4]: b
Out[4]: array([7., 7., 7.])

In [5]: type(b)
Out[5]: cupy.core.core.ndarray

In [6]: b = np.full_like(a, 7, shape=(2, 2))  # You can override properties such as `shape`

In [7]: b
Out[7]:
array([[7., 7.],
       [7., 7.]])

In [8]: type(b)
Out[8]: cupy.core.core.ndarray

@pentschev
Copy link

I see now that the above has already been proposed in #10836 (comment). Note that like= may not achieve the desired result in that case either, because we'll only pass the array type downstream (in this case, u.Quantity), but properties will still need to be specified in np.full's constructor.

@mhvk
Copy link
Contributor

mhvk commented Oct 28, 2020

@pentschev - indeed, np.full_like is already supported. I think that like= would work, as all we'd need was indeed the class. But I had forgotten that, as you note, full_like is quite similar already to full(..., like=), since one can override the shape and other properties. So,

my_q = 1.*u.m
np.full_like(my_q, my_q, shape=(10,))
# <Quantity [1., 1., 1., 1., 1., 1., 1., 1., 1., 1.] m>

works. It would have been nice if the fill_value defaulted to the input array if that is a scalar...

@pentschev
Copy link

It would have been nice if the fill_value defaulted to the input array if that is a scalar...

Given that full_like is sort of an extension to fill, I guess this was a design decision, as fill_value is a required argument in full. But I see in the example above how it looks weird, unfortunately I think we don't have a better solution at the moment.

@mhvk
Copy link
Contributor

mhvk commented Oct 28, 2020

@pentschev - yes, no problem! I don't quite think this is worth (slightly) changing the numpy API for.

@mhvk
Copy link
Contributor

mhvk commented Apr 12, 2021

Update: like= now is supported in numpy 1.20, so we should gain an override method. For np.full, that could look at the fill argument and infer the unit from that.

@pllim
Copy link
Member

pllim commented Jan 25, 2023

Update with astropy 5.2.1 , it no longer throw exception but it also loses unit.

>>> np.full(10, my_quantity)
array([1., 1., 1., 1., 1., 1., 1., 1., 1., 1.])

@MridulS MridulS linked a pull request Mar 1, 2024 that will close this issue
1 task
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants