Skip to content

BUG np.broadcast_arrays does not work on void arrays with object fields #5081

Closed

Description

@mhvk

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.

Activity

  1. shoyer commented on Dec 7, 2014

    @shoyer
    Member

    Hmm. I thought we fixed this in #4408.

  2. mhvk commented on Dec 7, 2014

    @mhvk
    ContributorAuthor

    @shoyer - sadly, no. I checked just to be sure and this is still an issue with current master.

  3. jaimefrio commented on Jan 26, 2015

    @jaimefrio
    Member

    I see two ways of going about fixing this:

    1. 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.
    2. 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.

    Any thoughts?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions