-
Notifications
You must be signed in to change notification settings - Fork 2
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
easier way to create arrays #6
Comments
Your second example should work. And import marray
import numpy as np
xp = marray.masked_array(np)
a = xp.asarray(np.arange(10), mask=(np.arange(10) % 2 == 0)) ? Currently |
That's interesting, I totally missed that. I was under the (quite possibly mistaken?) assumption that the Array API didn't allow adding additional arguments, so I didn't even bother to check. |
I'm not certain whether the standard disallows that sort of thing, but NumPy 2.1 |
@keewis this is now: import marray
import numpy as np
mxp = marray.get_namespace(np)
a = mxp.asarray(np.arange(10), mask=(np.arange(10) % 2 == 0))
# MArray(
# array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]),
# array([ True, False, True, False, True, False, True, False, True,
# False])
# ) which is no longer than the suggestions in #6 (comment).
# draft just to illustrate
# subclasses might not work correctly as-written
class MArray:
def __new__(self, data, mask=None):
xp = data.__array_namespace__()
mxp = get_namespace(xp)
return mxp.MArray(data=data, mask=mask) But my impression from your second suggestion is that four lines is short enough. Is this issue resolved? |
I don't think we have to go as far as implementing def create_marray(data, mask=None):
if mask is None:
# standard `array_namespace` function, similar to what is defined by `array_api_compat`
xp = array_namespace(data)
else:
xp = array_namespace(data, mask)
mxp = marray.get_namespace(xp)
return mxp.MArray(data=data, mask=mask) (As an aside, I don't love the name of Edit: to make it clear, the requirement to create the namespace first feels inconvenient, which the only complaint I have, other than feeling somewhat uneasy about modifying the signature of |
It is possible to get around this for any function that accepts an array as input, but it is not without downsides. Off the top of my head:
This is all quite a price to pay for users adding a single line in addition to the import. Maybe something to think about for a MArray 2.0, since it has almost no impact on user code? I'd rather get something working within the existing structure for now. This comment is relevant: |
We do not currently follow the positional-only, keyword-only conventions perfectly, so I think there are bigger fish to fry w.r.t. to the functions accepting more arguments than they should (gh-16). So that aside: with See also https://data-apis.org/array-api/latest/purpose_and_scope.html#conformance. it states that all the required things must be present, but it indicates that additional features may be present. It does not specifically mention additional keyword only arguments. But it says we can document our level of incompatibility. I would suggest we just document this one additional keyword argument as a potential "incompatibility", if adding a keyword is considered incompatible (even though only introspection would be able to detect the incompatibility in a test). Resolved by data-apis/array-api#869 / data-apis/array-api#870. Conforming implementations may add additional arguments to functions. |
closing now that we can use |
I think so. I think the only alternative on the table was that we could expose import numpy as np
import marray
x = marray.MArray([1, 2, 3]) So in theory you could use its methods after three lines instead of four. But as soon as you need to get functions from the associated namespace, you'd need:
adding an ugly fourth line. I don't think this is worth it, considering the alternative is also four line long, looks cleaner, and avoids having to make the |
I was thinking that this pattern: import marray
x = marray.MArray(np.array([1, 2, 3]))
xp = x.__array_namespace__()
xp.exp(x) was what you'd always get with the array API, unless you use the namespace directly (or at least, that was my impression when working on Under that assumption the closest to ideal would be this: import marray as ma
x = ma.MArray(np.array([1, 2, 3]))
ma.exp(x)
# equivalent to
xp = x.__array_namespace__()
xp.exp(x) but I guess since adding additional args / kwargs is explicitly allowed, the current state is fine. I guess now the only issues I have is the registering of |
Pull requests would be even better! But yes, please.
|
I think I disagree - this goes back to our discussion at data-apis/array-api#843 (comment). Here's my reasoning:
For xarray, a dispatching module like Something that arises from this: in data-apis/array-api#843 (comment) I discuss the idea of a |
To be clear about the problem I see with the current In [1]: import numpy as np
In [2]: import array_api_strict as xp
In [3]: import marray
In [4]: mnp = marray.get_namespace(np)
In [5]: mxp = marray.get_namespace(xp)
In [6]: xp1 = mnp.arange(2).__array_namespace__()
In [7]: xp1.__name__
Out[7]: 'mxp'
In [8]: xp1.arange(2).data.__array_namespace__().__name__
Out[8]: 'numpy'
In [9]: xp2 = mxp.arange(3).__array_namespace__()
In [10]: xp2.__name__
Out[10]: 'mxp'
In [11]: xp2.arange(3).data.__array_namespace__().__name__
Out[11]: 'array_api_strict' The modules behave differently since they have different array backends, but have the same name. I guess the same goes for |
While the idea of using a function to create a nested namespace is neat, it makes creating arrays harder:
What I'd like to have (but don't quite know how easy it is to support, nor if it actually is a good idea) is something like this:
Alternatively, this could also work (since the Array API doesn't forbid adding non-standard things to the namespace):
However, I would imagine that this makes creating / composing arrays a bit harder. And since we don't subclass arrays classes anymore, maybe we don't even need the dynamic namespace (and thus the meta-programming)?
The text was updated successfully, but these errors were encountered: