Why is the list of tuples a useful thing to have in the first place? If the goal is to convert an array into a structured array, you can do that far more efficiently with:

def make_tup_dtype(arr):
    """
    Attempt to make a type capable of viewing the last axis of an array, even if it is non-contiguous.
    Unfortunately `.view` doesn't allow us to use this dtype in that case, which needs a patch...
    """
    n_fields = arr.shape[-1]
    step = arr.strides[-1]
    descr = dict(names=[], formats=[], offsets=[], itemsize=step * n_fields)
    for i in range(n_fields):
        descr['names'].append('f{}'.format(i))
        descr['offsets'].append(step * i)
        descr['formats'].append(arr.dtype)
    return np.dtype(descr)

Used as:

>>> arr = np.arange(6).reshape(3, 2)
>>> arr.view(make_tup_dtype(arr)).squeeze(axis=-1)
array([(0, 1), (2, 3), (4, 5)],
      dtype=[('f0', '<i4'), ('f1', '<i4')])

Perhaps this should be provided by recfunctions (or maybe it already is, in a less rigid form?)

Eric


On Fri, 26 Jan 2018 at 10:48 Allan Haldane <allanhaldane@gmail.com> wrote:
On 01/25/2018 08:53 PM, Chris Barker - NOAA Federal wrote:
>> On Jan 25, 2018, at 4:06 PM, Allan Haldane <allanhaldane@gmail.com> wrote:
>
>>> 1) This is a known change with good reason?
>
>> . The
>> change occurred because the old assignment behavior was dangerous, and
>> was not doing what you thought.
>
> OK, that’s a good reason!
>
>>> A) improve the error message.
>>
>> Good idea. I'll see if we can do it for 1.14.1.
>
> What do folks think about a totuple() method — even before this I’ve
> wanted that. But in this case, it seems particularly useful.
>
> -CHB

Two thoughts:

1. `totuple` makes most sense for 2d arrays. But what should it do for
1d or 3+d arrays? I suppose it could make the last dimension a tuple, so
1d arrays would give a list of tuples of size 1.

2. structured array's .tolist() already returns a list of tuples. If we
have a 2d structured array, would it add one more layer of tuples? That
would raise an exception if read back in by `np.array` with the same dtype.

These points make me think that instead of a `.totuple` method, this
might be more suitable as a new function in np.lib.recfunctions. If the
goal is to help manipulate structured arrays, that submodule is
appropriate since it already has other functions do manipulate fields in
similar ways. What about calling it `pack_last_axis`?

def pack_last_axis(arr, names=None):
    if arr.names:
        return arr
    names = names or ['f{}'.format(i) for i in range(arr.shape[-1])]
    return arr.view([(n, arr.dtype) for n in names]).squeeze(-1)

Then you could do:

    >>> pack_last_axis(uv).tolist()

to get a list of tuples.

Allan
_______________________________________________
NumPy-Discussion mailing list
NumPy-Discussion@python.org
https://mail.python.org/mailman/listinfo/numpy-discussion