-
-
Notifications
You must be signed in to change notification settings - Fork 9.5k
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
BUG: Zero-dimensional numpy arrays within records decay to scalars #9442
Comments
There're two parts to this. The error you're getting is the same as this one: b = np.zeros(3, np.bool)
b[0][()] = np.ones((), dtype=np.bool) Which is because a The other problem is that your dtype is being ignored: >>> a.dtype
dtype([('k', '<u8'), ('t', '<f4'), ('d', '?')]) In general, it seems to be impossible to specify a 0d subdtype: >>> np.dtype((np.bool_, (2,))).subdtype
(dtype('bool'), (2,))
>>> np.dtype((np.bool_, ())).subdtype
None This is arguably a bug |
Here's the code that deliberately ignores a shape of |
Even removing that doesn't help though, as huge amounts of numpy functions end along the lines of
|
A workaround would be to index as |
Thanks for linking the code. I was going to ask you if I could help, but I'm very busy right now. I may come back to this. I don't understand your workaround in the context of my second definition of |
Here it is for each of your two definitions of
The workaround works by first avoiding indexing a
|
That works, but it doesn't make any sense to me 😄 |
Step by step: i = () # or 3, in your other example
a[0][2][i] # original
a[0]['d'][i] # index by field name, not field index
a['d'][0][i] # field name index can go anywhere
a['d'][0,...][i] # adding ... makes this return a 0d array, not an np.bool_
|
Got it, thanks. |
To summarize, I think the underlying bug here is a total lack of support for distinguishing 0d fields and scalar fields in a subdtype. I don't think there's an easy fix, because part of the problem is that subdtypes are not first-class citizens in the dtype world, as they decay very quickly into extra dimensions. |
I don't know enough about how they're implemented, but I guess you can't just remove that condition in the code that you linked? |
I've tried that, and it doesn't help. The next problem is that |
I think that subdtype expansion is an important consideration. Such an expansion is one of the most common ways of using a structured array. Most of the |
The type of (compatibility-breaking) change I'm envisaging is: >>> a_dt = np.dtype([('v', int, (3,))])
>>> a = np.empty(4, a_dt)
>>> x = a['x'] # new behaviour
>>> x.dtype
dtype(('<i4', 3))
>>> x.shape
(4,)
>>> x_old = x.view(int) # workaround to regain the old behaviour
>>> x_old.dtype
dtype('<i4')
>>> x_old.shape
(4,3) Of course, that's the type of change we can never make, unless we start using context managers to enable new semantics |
You could keep a list of all of the breaking changes you would like to make, and then if that list gets long enough, one day, implement that context manager? (Because I agree, this is not super-motivating.) |
Actually, it turns out that context managers over global state are not a safe way to change semantics: #9444 |
That's fascinating. I don't know the answer. Please consider posting this to python-ideas to start a discussion about how this is supposed to work. |
First, a shape (4,) numpy array within a record can be assigned:
But, a shape () cannot:
But if it's not in a record, it works just fine:
The text was updated successfully, but these errors were encountered: