[Numpy-discussion] Add a function to broadcast arrays to a given shape to numpy's stride_tricks?

Nathaniel Smith njs at pobox.com
Wed Dec 10 19:00:36 EST 2014


On Sun, Dec 7, 2014 at 7:10 AM, Stephan Hoyer <shoyer at gmail.com> wrote:
> I recently wrote function to manually broadcast an ndarray to a given shape
> according to numpy's broadcasting rules (using strides):
> https://github.com/xray/xray/commit/7aee4a3ed2dfd3b9aff7f3c5c6c68d51df2e3ff3
>
> The same functionality can be done pretty straightforwardly with
> np.broadcast_arrays, but that function does both too much (I don't actually
> have a second array that needs to be broadcast) and not enough (I need to
> create a dummy array to broadcast against it).
>
> This approach is simpler, and also, according to my benchmarks, about 3x
> faster than np.broadcast_arrays:
>
> In [1]: import xray
> In [2]: import numpy as np
> In [3]: x = np.random.randn(4)
> In [4]: y = np.empty((2, 3, 4))
> In [5]: %timeit xray.core.utils.as_shape(x, y.shape)
> 100000 loops, best of 3: 17 µs per loop
> In [6]: %timeit np.broadcast_arrays(x, y)[0]
> 10000 loops, best of 3: 47.4 µs per loop
>
> Would this be a welcome addition to numpy's lib.stride_tricks? If so, I will
> put together a PR.
>
> In my search, I turned up a Stack Overflow post looking for similar
> functionality:
> https://stackoverflow.com/questions/11622692/is-there-a-better-way-to-broadcast-arrays

Seems like a useful addition to me -- I've definitely wanted this in
the past. I agree with Stephan that reshape() might not be the best
place, though; I wouldn't think to look for it there.

Two API ideas, which are not mutually exclusive:

1) Give broadcast_arrays an extra_shapes=[shape1, shape2, ...]
argument. Each entry in that list is a tuple of integers;
broadcast_arrays chooses the final output shape "as if" additional
arrays with the given shapes had been passed in, in addition to the
ones in *args.

2) Add a broadcast_to(arr, shape) function, which broadcasts the array
to exactly the shape given, or else errors out if this is not
possible.

Given (1), (2) could just be:

def broadcast_to(arr, shape):
    output = broadcast_arrays(arr, extra_shapes=[shape])
    if output.shape != shape:
        raise ...
    return output

-n

-- 
Nathaniel J. Smith
Postdoctoral researcher - Informatics - University of Edinburgh
http://vorpus.org



More information about the NumPy-Discussion mailing list