You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
shape-1 fields in dtypes are collapsed to scalars #13112
import numpy as np
t = np.empty(1, [
("a", int),
("b", int, ()),
("c", int, 1),
("d", int, (1,)),
("e", int, 2),
("f", int, (2,)),
])
for field in "abcdef":
print(t[field].shape)
This prints
(1,)
(1,)
(1,)
(1, 1)
(1, 2)
(1, 2)
i.e. the ("c", int, 1) field is treated as a scalar, but not the ("d", int, (1,)) field.
While a careful reading of https://docs.scipy.org/doc/numpy/reference/arrays.dtypes.html does show that this behavior is documented ("Note that a 3-tuple with a third argument equal to 1 is equivalent to a 2-tuple."), it looks a bit contrary to normal expectations (for most numpy functions, when a single integer is allowed where a shape is expected, that single integer is usually treated as a single-element tuple containing that value). Note that there are already two other ways to specify a scalar field (either don't pass the shape at all, or pass an empty tuple), so it would be nice if the behavior of ("c", int, 1) could be made more consistent.
Reproducing code example:
(see above)
Numpy/Python version information:
1.16.2 3.7.2 (default, Dec 29 2018, 06:19:36)
[GCC 7.3.0]
(The nice thing is that a deprecation path is available: if one passes 1 as shape, emit a warning asking to either use () [or no shape at all] or (1,) depending on what they want).
* If (type, 1) was given, it is equivalent to type...
* or (type, ()) was given it is equivalent to type...
*/
if ((shape.len==1
&&shape.ptr[0] ==1
&&PyNumber_Check(val))
|| (shape.len==0
&&PyTuple_Check(val))) {
npy_free_cache_dim_obj(shape);
returntype;
}
Note that the (type, 1) → type alias was added deliberately in 071f111, while (type, ()) → type was added 9 months later in 87e3010. Had () come first, I doubt we would have ever added 1.
Activity
eric-wieser commentedon Mar 13, 2019
I'd be in favor of deprecating this - I introduced a bug internally thanks to this at some point.
anntzer commentedon Mar 13, 2019
(The nice thing is that a deprecation path is available: if one passes 1 as shape, emit a warning asking to either use () [or no shape at all] or (1,) depending on what they want).
eric-wieser commentedon Apr 14, 2019
@anntzer: Want to make a PR to deprecate this?
anntzer commentedon Apr 14, 2019
I have no idea where the logic for dtype construction is :/
eric-wieser commentedon Apr 14, 2019
numpy/numpy/core/src/multiarray/descriptor.c
Lines 283 to 294 in fb425b7
Note that the
(type, 1)→typealias was added deliberately in 071f111, while(type, ())→typewas added 9 months later in 87e3010. Had()come first, I doubt we would have ever added1.seberg commentedon Jul 12, 2019
The deprecation is ongoing and in 1.17 now, so I think I will close tihs issue.