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
BUG np.broadcast_arrays does not work on void arrays with object fields #5081
In the process of working on #4622, it was realised that np.broadcas_arrays do not work for void arrays with object fields, because in the process of changing new strides and shapes in as_strided, the dtype gets lost, and this cannot just be reset when object fields are present. While obviously this is somewhat of a corner case, it might still be good to see if it can be fixed easily, perhaps by doing something that preserves the dtype, or by bypassing the test for object fields.
import numpy as np
dt = np.dtype([('x', 'i8'), ('y', '?'), ('z', 'O')])
b = np.array([(1, True, None), (2, False, [3, 4, 5])], dtype=dt)
c = np.array([[-1], [-2]])
b_strided, c_strided = np.broadcast_arrays(b, c)
TypeError Traceback (most recent call last)
...
/usr/lib/python3/dist-packages/numpy/lib/stride_tricks.py in as_strided(x, shape, strides)
31 # Make sure dtype is correct in case of custom dtype
32 if array.dtype.kind == 'V':
---> 33 array.dtype = x.dtype
34 return array
35
TypeError: Cannot change data-type for object array.
One is to modify PyArray_FromInterface, which lives in numpy\core\src\multiarray.ctors.c. It is currently using the 'typestr' entry of the __array_interface__ dictionary to determine the dtype, and completely ignores the 'descr' optional entry. The idea would be to, if the resulting type created from 'typestr' is NPY_VOID, recreate the dtype from 'descr', with all the necessary checks to see that both dtypes are compatible, and use the latter to instantiate the array.
We could also simply rewrite as_strided in C with a call to PyArray_NewFromDescr, reusing the dtype of the passed-in object, which shouldn't have these type of issues.
The first approach seems the correct one, but it may create backwards compatibility headaches, and is more involved to get right. The second is very straightforward, but it would hide in the C code the nice example of how to do cool things with __array_interface__ from pure Python that as_strided is right now.
Activity
shoyer commentedon Dec 7, 2014
Hmm. I thought we fixed this in #4408.
mhvk commentedon Dec 7, 2014
@shoyer - sadly, no. I checked just to be sure and this is still an issue with current master.
jaimefrio commentedon Jan 26, 2015
I see two ways of going about fixing this:
PyArray_FromInterface, which lives innumpy\core\src\multiarray.ctors.c. It is currently using the'typestr'entry of the__array_interface__dictionary to determine the dtype, and completely ignores the'descr'optional entry. The idea would be to, if the resulting type created from'typestr'isNPY_VOID, recreate the dtype from'descr', with all the necessary checks to see that both dtypes are compatible, and use the latter to instantiate the array.as_stridedin C with a call toPyArray_NewFromDescr, reusing the dtype of the passed-in object, which shouldn't have these type of issues.The first approach seems the correct one, but it may create backwards compatibility headaches, and is more involved to get right. The second is very straightforward, but it would hide in the C code the nice example of how to do cool things with
__array_interface__from pure Python thatas_stridedis right now.Any thoughts?