Looks gorgeous, thank you to all who worked on the implementation, API, and 
review, and thank you Sebastian for saving me a click! 😂

> On 13 Oct 2020, at 2:25 am, Sebastian Berg <sebast...@sipsolutions.net> wrote:
> 
> On Mon, 2020-10-12 at 08:39 +0000, Zimmermann Klaus wrote:
>> Hello,
>> 
>> I would like to draw the attention of this list to PR #17394 [1] that
>> adds the implementation of a sliding window view to numpy.
>> 
> 
> Hi,
> 
> thanks for working on this and driving going forward. I like the choice of a 
> minimal API.  I have pasted the doc-string (html, hope that works fine) below 
> to allow a quicker idea of what is being proposed.  To me it looks good! (I 
> wonder if we need `subok`, but I guess we probably do.)
> 
> Cheers,
> 
> Sebastian
> 
> 
> numpy.sliding_window_view 
> <https://16171-908607-gh.circle-artifacts.com/0/doc/build/html/reference/generated/numpy.sliding_window_view.html#numpy-sliding-window-view>
> numpy.sliding_window_view(x, window_shape, axis=None, *, subok=False, 
> writeable=False) 
> <https://16171-908607-gh.circle-artifacts.com/0/doc/build/html/reference/generated/numpy.sliding_window_view.html#numpy.sliding_window_view>
> Create a sliding window view into the array with the given window shape.
> 
> Creates a sliding window view of the N dimensional array with the given 
> window shape. Window slides across each dimension of the array and extract a 
> subsets of the array at any window position.
> 
> Parameters
> x : array_like
> Array to create the sliding window view from.
> window_shape : int or tuple of int
> Size of window over each axis that takes part in the sliding window. If axis 
> is not present, must have same length as the number of input array 
> dimensions. Single integers i are treated as if they were the tuple (i,).
> axis : int or tuple of int, optional
> Axis or axes along which the sliding window is applied. By default, the 
> sliding window is applied to all axes and window_shape[i] will refer to axis 
> i of x. If axis is given as a tuple of int, window_shape[i] will refer to the 
> axis axis[i] of x. Single integers i are treated as if they were the tuple 
> (i,).
> subok : bool, optional
> If True, sub-classes will be passed-through, otherwise the returned array 
> will be forced to be a base-class array (default).
> writeable : bool, optional
> When true, allow writing to the returned view. The default is false, as this 
> should be used with caution: the returned view contains the same memory 
> location multiple times, so writing to one location will cause others to 
> change.
> Returns
> view : ndarray
> Sliding window view of the array. The sliding window dimensions are inserted 
> at the end, and the original dimensions are trimmed as required by the size 
> of the sliding window.
> That is, view.shape = x_shape_trimmed + window_shape, where x_shape_trimmed 
> is x.shape with every entry reduced by one less than the corresponding window 
> size.
> See also
> lib.stride_tricks.as_strided 
> <https://16171-908607-gh.circle-artifacts.com/0/doc/build/html/reference/generated/numpy.lib.stride_tricks.as_strided.html#numpy.lib.stride_tricks.as_strided>
> Create a view into the array with the given shape and strides.
> broadcast_to 
> <https://16171-908607-gh.circle-artifacts.com/0/doc/build/html/reference/generated/numpy.broadcast_to.html#numpy.broadcast_to>
> broadcast an array to a given shape.
> Notes
> 
> For some cases there may be more efficient approaches to calculate 
> transformations across multi-dimensional arrays, for instance 
> scipy.signal.fftconvolve 
> <https://docs.scipy.org/doc/scipy/reference/generated/scipy.signal.fftconvolve.html#scipy.signal.fftconvolve>,
>  where combining the iterating step with the calculation itself while storing 
> partial results can result in significant speedups.
> 
> Examples
> 
> >>> x = np.arange(6)
> >>> x.shape
> (6,)
> >>> v = np.sliding_window_view(x, 3)
> >>> v.shape
> (4, 3)
> >>> v
> array([[0, 1, 2],
>        [1, 2, 3],
>        [2, 3, 4],
>        [3, 4, 5]])
> This also works in more dimensions, e.g.
> 
> >>> i, j = np.ogrid[:3, :4]
> >>> x = 10*i + j
> >>> x.shape
> (3, 4)
> >>> x
> array([[ 0,  1,  2,  3],
>        [10, 11, 12, 13],
>        [20, 21, 22, 23]])
> >>> shape = (2,2)
> >>> v = np.sliding_window_view(x, shape)
> >>> v.shape
> (2, 3, 2, 2)
> >>> v
> array([[[[ 0,  1],
>          [10, 11]],
>         [[ 1,  2],
>          [11, 12]],
>         [[ 2,  3],
>          [12, 13]]],
>        [[[10, 11],
>          [20, 21]],
>         [[11, 12],
>          [21, 22]],
>         [[12, 13],
>          [22, 23]]]])
> The axis can be specified explicitly:
> 
> >>> v = np.sliding_window_view(x, 3, 0)
> >>> v.shape
> (1, 4, 3)
> >>> v
> array([[[ 0, 10, 20],
>         [ 1, 11, 21],
>         [ 2, 12, 22],
>         [ 3, 13, 23]]])
> The same axis can be used several times. In that case, every use reduces the 
> corresponding original dimension:
> 
> >>> v = np.sliding_window_view(x, (2, 3), (1, 1))
> >>> v.shape
> (3, 1, 2, 3)
> >>> v
> array([[[[ 0,  1,  2],
>          [ 1,  2,  3]]],
>        [[[10, 11, 12],
>          [11, 12, 13]]],
>        [[[20, 21, 22],
>          [21, 22, 23]]]])
> Combining with stepped slicing (::step), this can be used to take sliding 
> views which skip elements:
> 
> >>> x = np.arange(7)
> >>> np.sliding_window_view(x, 5)[:, ::2]
> array([[0, 2, 4],
>        [1, 3, 5],
>        [2, 4, 6]])
> or views which move by multiple elements
> 
> >>> x = np.arange(7)
> >>> np.sliding_window_view(x, 3)[::2, :]
> array([[0, 1, 2],
>        [2, 3, 4],
>        [4, 5, 6]])
> 
> 
> 
> 
> 
>> Having a sliding window view in numpy is a longstanding open issue (cf
>> #7753 [2] from 2016). A brief summary of the discussions surrounding it
>> can be found in the description of the PR.
>> 
>> This PR implements a sliding window view based on stride tricks.
>> Following the discussion in issue #7753, a first implementation was
>> provided by Fanjin Zeng in PR #10771. After some discussion, that PR
>> stalled and I picked up the issue in the present PR #17394. It is based
>> on the first implementation, but follows the changed API as suggested by
>> Eric Wieser.
>> 
>> Code reviews have been provided by Bas van Beek, Stephen Hoyer, and Eric
>> Wieser. Sebastian Berg added the "62 - Python API" label.
>> 
>> 
>> Do you think this is suitable for inclusion in numpy?
>> 
>> Do you consider the PR ready?
>> 
>> Do you have suggestions or requests?
>> 
>> 
>> Thanks for your time and consideration!
>> Klaus
>> 
>> 
>> [1] https://github.com/numpy/numpy/pull/17394 
>> <https://github.com/numpy/numpy/pull/17394>
>> [2] https://github.com/numpy/numpy/issues/7753 
>> <https://github.com/numpy/numpy/issues/7753>
>> _______________________________________________
>> NumPy-Discussion mailing list
>> NumPy-Discussion@python.org <mailto:NumPy-Discussion@python.org>
>> https://mail.python.org/mailman/listinfo/numpy-discussion 
>> <https://mail.python.org/mailman/listinfo/numpy-discussion>
>> 
> 
> _______________________________________________
> NumPy-Discussion mailing list
> NumPy-Discussion@python.org <mailto:NumPy-Discussion@python.org>
> https://mail.python.org/mailman/listinfo/numpy-discussion 
> <https://mail.python.org/mailman/listinfo/numpy-discussion>
_______________________________________________
NumPy-Discussion mailing list
NumPy-Discussion@python.org
https://mail.python.org/mailman/listinfo/numpy-discussion

Reply via email to